C 多线程同步
我正在使用glibc pthreads库编写一个多线程应用程序。我有3个pthread——其中一个称为“调度器”,另外两个称为“工作线程”和主线程。主线程侦听事件并将它们放入队列中。然后调度程序线程将它们分派到工作队列。工作线程从工作队列中拾取事件并执行。问题是,有时必须在主线程中执行事件,以防止主要的数据争用。因此,我需要一种机制,在接收到特殊事件时暂停主线程,并等待所有工作人员完成其工作,然后执行此事件 为了做到这一点,我使用了一个受互斥保护的整数,由工作线程设置和重置whos位。当工作进程在其队列中找不到作业时,它会将其位设置为0。如果有作业,则它将其位标记为1。这个想法是,如果其中一个工人正在运行,那么整数是!=0现在,当主线程想要暂停自身以便工作线程完成时,它将执行一个条件等待,直到整数变为0。工作线程在重置其位时将检查整数是否变为0。如果为true,则它将向主线程发送信号。在这一点上,我希望所有工人在他们的队列中都没有作业,因此主线程可以执行特殊事件。因为主线程负责将事件排队到第一个队列,所以我们保证不会有任何事件潜入工作线程 伪代码如下所示C 多线程同步,c,multithreading,C,Multithreading,我正在使用glibc pthreads库编写一个多线程应用程序。我有3个pthread——其中一个称为“调度器”,另外两个称为“工作线程”和主线程。主线程侦听事件并将它们放入队列中。然后调度程序线程将它们分派到工作队列。工作线程从工作队列中拾取事件并执行。问题是,有时必须在主线程中执行事件,以防止主要的数据争用。因此,我需要一种机制,在接收到特殊事件时暂停主线程,并等待所有工作人员完成其工作,然后执行此事件 为了做到这一点,我使用了一个受互斥保护的整数,由工作线程设置和重置whos位。当工作进程
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));
}
int pause_threads()=>从主线程调用的线程。
{
pthread_mutex_lock(pause_thread_lock));
而(pthread_states!=0){
pthread_cond_wait(pause_mthread_cond),pause_thread_lock);
}
}
int thread_resume()=>在主线程执行特殊事件后调用。
{
pthread_mutex_unlock(暂停_线程_锁));
}
int-thread\u-set\u-state\u-wait(index)=>每个工作线程的索引id为0,1
{
pthread_mutex_lock(pause_thread_lock));
(thread_states)&=(~(MTHREAD_THR_STATE_RUNNING这是一个棘手的问题。当您的主例程将进入关键部分时,它需要确保:
调度程序不会安排更多的工作
工人们完成了他们的工作
这两种机制都需要其他线程的确认。如果您建立某种消息传递机制或使用预先存在的机制,那么将其作为通信问题写出来可能会更容易。不过,使用标准的互斥体和condvar集,您可能会将其结构如下:
- 调度程序
- 安排工作时,在飞行中增加作业(由互斥锁锁定)
- 工人
- 完成工作和广播时减少飞行中的作业(由互斥锁锁定)
- 主要
- 当它需要一个临界段时,它设置一个标志(由互斥锁锁定)表示临界段正在进行,并在一个condvar上广播此状态已更改
- 设置一个标志(也被锁定),表示条目正在进行并广播状态更改
- 它通过将标志设置为零,等待调度程序确认正在进行的条目condvar
- 它在飞行中等待工作人员完成
- 取消设置正在进行的进程并广播以取消阻止计划程序
- 调度程序
- 在开始工作之前或在condvar上进行检查,以查看main是否要进入
- 取消设置条目进行中标志并广播以确认
- 等待main完成的关键进行中condvar
当所有这些都准备就绪后,main可以确保不再计划更多的工作,并且所有正在进行的工作都已完成。它可以完成它的工作,然后取消阻止计划程序。错误的同步原语。使用信号量。@n.m.为什么要使用信号量?等待条件是条件变量的作用。@victorram you ne“我不希望使用任何多线程同步机制,如(信号量、互斥)。”…此时,我希望所有工人在他们的队列中都没有作业…”为什么?队列中可能还有一些内容。对我来说,这看起来很好。当其中一个队列中有一个静态事件时,可能存在竞争条件。主线程停止生成新事件,等待所有工作线程空闲(片刻)然后开始处理事件,但在下一刻,工作线程可以从仍然满的队列中抓取事件。将其与信号量解决方案进行比较。从初始值2开始。工作线程:P;do work;V.主线程,临界区:P;P;do work;V;V.调度器:退后观看节目。@n.m.确实如此。但是,这并不是g我让调度器能够灵活地运行当前工作负载所需的尽可能多的线程,因此从长远来看,这可能不是一个好的解决方案。当然,有很多方法可以简化我编写的内容。为什么,也很容易将这种可能性结合起来。在这种情况下,例如,调度器代表主线程执行P/V操作;t主线程必须要求调度程序将正在运行的线程数设置为0。因为它们之间已经有了通信通道,所以应该很容易实现。使用Kyle的“正在运行的作业”思想,我们可以使它更简单。因为主线程控制传递给调度程序的事件,所以它可以直接影响调度程序。所以算法是这样的:1.当主线程将事件传递给调度程序时,它会增加飞行中的作业2.工作线程在处理事件时会减少飞行中的作业3.当主线程想要处理特殊事件时,它会有条件地等待飞行中的作业变为零4.当飞行中的作业变为0时,工作线程会减少投射信号。即使Main没有执行条件等待,也会发生这种情况。