【问题标题】:How to get threads to execute in a certain order?如何让线程按特定顺序执行?
【发布时间】:2014-03-07 20:37:03
【问题描述】:

我查阅的几乎所有资源都谈到了如何强制互斥,或处理生产者/消费者问题。

问题是我需要让某些线程在其他线程之前执行,但不知道如何。我正在尝试使用信号量,但并没有真正看到它们对我的情况有何帮助。

我有

  • 一个读线程,
  • N 个搜索线程,以及
  • 写线程。

读取线程用数据填充缓冲区,然后搜索线程解析数据并将其输出到不同的缓冲区,然后写入线程将其写入文件。

知道我将如何实现这一点吗?

如果有人认为有帮助,我可以发布我目前拥有的代码。

【问题讨论】:

  • 这正是信号量的一般用途,你确定你对它们的工作原理和作用有很好的了解吗?
  • 如果您有一个线性程序逻辑并且不希望您的线程同时运行,为什么要将您的代码拆分成单独的线程?
  • 我的想法是将信号量初始化为负数(搜索线程数),然后让每个搜索线程在完成时发出信号以增加信号量。写线程将等待信号量为零,因此当所有搜索线程完成时它会唤醒。但显然你不能将信号量初始化为负值。
  • 搜索线程确实同时运行,我只需要在写线程从缓冲区读取之前完成它们。
  • 确实如此。信号量的计数存储在不能低于 0 的 unsigned int

标签: c multithreading pthreads


【解决方案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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-17
        • 1970-01-01
        • 1970-01-01
        • 2018-05-03
        • 1970-01-01
        • 2014-07-13
        • 2018-08-21
        • 2014-12-14
        相关资源
        最近更新 更多