如何让线程按特定顺序执行?
Posted
技术标签:
【中文标题】如何让线程按特定顺序执行?【英文标题】:How to get threads to execute in a certain order? 【发布时间】:2014-03-07 20:37:03 【问题描述】:我查阅的几乎所有资源都谈到了如何强制互斥,或处理生产者/消费者问题。
问题是我需要让某些线程在其他线程之前执行,但不知道如何。我正在尝试使用信号量,但并没有真正看到它们对我的情况有何帮助。
我有
一个读线程, N 个搜索线程,以及 写线程。读取线程用数据填充缓冲区,然后搜索线程解析数据并将其输出到不同的缓冲区,然后写入线程将其写入文件。
知道我将如何实现这一点吗?
如果有人认为有帮助,我可以发布我目前拥有的代码。
【问题讨论】:
这正是信号量的一般用途,你确定你对它们的工作原理和作用有很好的了解吗? 如果您有一个线性程序逻辑并且不希望您的线程同时运行,为什么要将您的代码拆分成单独的线程? 我的想法是将信号量初始化为负数(搜索线程数),然后让每个搜索线程在完成时发出信号以增加信号量。写线程将等待信号量为零,因此当所有搜索线程完成时它会唤醒。但显然你不能将信号量初始化为负值。 搜索线程确实同时运行,我只需要在写线程从缓冲区读取之前完成它们。 确实如此。信号量的计数存储在不能低于 0 的unsigned int
中
【参考方案1】:
我认为您正在寻找的是monitor
【讨论】:
一些附加信息here 在此处发布一些信息可能会有所帮助,但链接仍然存在 嗯,我真的不认为需要 C&P ***或内部 SO 链接。回到问题,你可以修改监视器的行为,允许多个消费者访问数据,但在生产者需要访问时阻止所有消费者。【参考方案2】:我会使用一些条件变量。
您已读取缓冲区。应该是两个吧。如果搜索线程很慢,您希望读取等待而不是使用缓冲区上的所有内存。
所以:一个 read_ready 条件变量和一个 read_ready_mutex。当有打开的缓冲区时设置为 true。
下一步:一个 search_ready 条件变量和一个 search_ready_mutex。当有完整的读取缓冲区时设置为 true。
下一步:一个 write_ready 变量和一个 write_ready 互斥锁。当写入线程有工作要做时设置为 true。
您可以使用准备好的缓冲区数量的整数,而不是 true/false。只要您在互斥锁被持有时验证条件,并且只在互斥锁被持有时修改条件,它就会起作用。
【讨论】:
【参考方案3】:[评论太长]
将其简化为两个假设:
在读取完成之前无法进行 Searchig。 在搜索完成之前无法写入。我总结:
不要使用线程进行读写,而是从主线程进行。 只需使用线程并行执行搜索即可。【讨论】:
【参考方案4】:一般来说,当我们不关心执行的顺序时,会精确地使用线程。 如果要按顺序执行某些语句 S1、S2、...、SN,则将它们连接到由单个线程运行的程序中: S1; S2; ...;序列号。
您描述的具体问题可以通过称为屏障的同步原语(实现为 POSIX 函数 pthread_barrier_wait
)来解决。
屏障用一个数字初始化,屏障计数为 N。调用屏障等待操作的线程被挂起,直到 N 个线程累积。然后他们都被释放了。其中一个线程收到一个返回值,告诉它它是“串行线程”。
例如,假设我们有 N 个线程执行此读取、并行处理和写入序列。它是这样的(伪代码):
i_am_serial = barrier.wait(); # at first, everyone waits at the barrier
if (i_am_serial) # serial thread does the reading, preparing the data
do_read_task();
barrier.wait(); # everyone rendezvous at the barrier again
do_paralallel_processing(); # everyone performs the processing on the data
i_am_serial = barrier.wait(); # rendezvous after parallel processing
if (i_am_serial)
do_write_report_task(); # serialized integration and reporting of results
【讨论】:
以上是关于如何让线程按特定顺序执行?的主要内容,如果未能解决你的问题,请参考以下文章