首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多线程同步

多线程同步
EN

Stack Overflow用户
提问于 2013-09-02 06:57:54
回答 1查看 165关注 0票数 0

我正在使用glibc线程库编写一个多线程应用程序。我有3个线程-其中一个称为“调度程序”,另两个称为“工作线程”和主线程。主线程侦听事件并将它们放入队列中。然后,调度器线程将它们分派到工作队列。辅助线程从工作队列中获取事件并执行。问题是,有时必须在主线程本身中执行事件,以防止主要的数据。因此,我需要一个机制来暂停主线程时,一个特殊的事件被接收,并等待直到所有的工人完成他们的工作,然后执行这个事件。

为了做到这一点,我使用一个由互斥保护的整数,其位由工作线程设置和重置。当工人在其队列中没有找到作业时,它会将其位设置为0。如果有一个作业,那么它会将它的位标记为1。意思是,如果其中一个工人正在运行,那么整数是!= 0。现在,当主线程想要暂停自己以让工作人员完成时,它现在将执行一个条件等待,直到整数变为0。工作线程在重置其位时将检查整数是否为0。如果为真,则将向主线程发出信号。此时,我希望所有工作人员的队列中都没有作业,因此主线程可以执行特殊事件。由于主线程负责第一个队列的排队事件,所以我们保证不会有任何事件溜到工人那里。

伪代码如下所示。

代码语言:javascript
复制
int pause_threads() => the one called from main thread.  
{  
  pthread_mutex_lock(pause_thread_lock));  

  while (pthread_states != 0) {  
  pthread_cond_wait(pause_mthread_cond), pause_thread_lock));  
  }  

}  

int thread_resume()  => called after the special event is executed by main thread.  
{  
  pthread_mutex_unlock(pause_thread_lock));  
}  

int thread_set_state_wait(index) => index is id 0,1 for each worker  
{  
 pthread_mutex_lock(pause_thread_lock));  
 (thread_states) &= (~(MTHREAD_THR_STATE_RUNNING << index));  
  if (pthread_states == 0)  
     pthread_cond_signal(pause_thread_cond));  
  pthread_mutex_unlock(&(pause_thread_lock));  
}  

 int thread_set_state_running(index)  
{  
   pthread_mutex_lock(pause_thread_lock));  
  (pthread_states) |= (MTHREAD_THR_STATE_RUNNING << index);  
   pthread_mutex_unlock(pause_thread_lock));  

}   

我面临的问题是,这段代码并不总是有效的。有时,我看到主线程在执行特殊事件时,工作线程仍然处于活动状态,并且正在执行作业。逻辑上有什么问题吗?还有其他可能的方法来实现这一点吗?我已经尽了最大努力去寻找解决办法。请帮帮忙。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-02 07:37:29

这是个棘手的问题。当您的主要例程要进入关键部分时,需要确保:

  1. 调度程序不会安排更多的工作
  2. 工人们完成了他们的工作

这两者都需要其他线程的确认。如果您创建某种消息传递机制或使用预先存在的机制,则可能更容易将其写成通信问题。不过,使用标准的互斥和秃鹰集合,您可能会将其构造为如下所示:

  • 调度程序
    1. 当调度工作时,在飞行中增加作业(被互斥锁住)

  • 工人
    1. 当完成工作和广播时,减少在飞作业(被互斥锁住)。

    1. 当它需要一个关键部分时,它设置一个标志(被互斥锁住),这个关键部分正在进行中,并在这个状态改变的condvar上广播。
    2. 设置一个标志(也是锁定的),该标志显示条目正在进行中,并广播状态更改。
    3. 它通过将标志设置为零来等待正在进行的条目condvar,以便调度程序确认。
    4. 它等待着飞行中的工作,等待工人们完成。
    5. 解除正在进行的进程并广播以解除阻塞调度程序。

  • 调度程序
    1. 在开始工作之前检查或在condvar上检查main是否要输入
    2. 取消正在进行的输入标志和广播以确认
    3. 等待关键正在进行的condvar以使main完成。

当所有这些都就位时,main可以确保不再安排更多的工作,并且所有正在运行的工作都完成了。它可以完成自己的任务,然后解除对调度程序的阻塞。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18567272

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档