Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 多线程同步_C_Multithreading - Fatal编程技术网

C 多线程同步

C 多线程同步,c,multithreading,C,Multithreading,我正在使用glibc pthreads库编写一个多线程应用程序。我有3个pthread——其中一个称为“调度器”,另外两个称为“工作线程”和主线程。主线程侦听事件并将它们放入队列中。然后调度程序线程将它们分派到工作队列。工作线程从工作队列中拾取事件并执行。问题是,有时必须在主线程中执行事件,以防止主要的数据争用。因此,我需要一种机制,在接收到特殊事件时暂停主线程,并等待所有工作人员完成其工作,然后执行此事件 为了做到这一点,我使用了一个受互斥保护的整数,由工作线程设置和重置whos位。当工作进程

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

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

伪代码如下所示

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没有执行条件等待,也会发生这种情况。