Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/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 Pthread条件等待和信号_C_Linux_Multithreading_Pthreads - Fatal编程技术网

C Pthread条件等待和信号

C Pthread条件等待和信号,c,linux,multithreading,pthreads,C,Linux,Multithreading,Pthreads,我对pthread_cond_wait和pthread_cond_信号函数有疑问。在阅读手册之后,我也无法理解 请考虑以下代码。 void* thread_handler(){ ... // counts till COUNT_LIMIT is reached if (count == COUNT_LIMIT) { pthread_cond_signal(&count_threshold_cv); printf("inc_count(): thread %ld, count =

我对pthread_cond_wait和pthread_cond_信号函数有疑问。在阅读手册之后,我也无法理解

请考虑以下代码。

void* thread_handler(){
... // counts till COUNT_LIMIT is reached
if (count == COUNT_LIMIT) {
  pthread_cond_signal(&count_threshold_cv);
  printf("inc_count(): thread %ld, count = %d  Threshold reached.\n",
         my_id, count);
}
printf("inc_count(): thread %ld, count = %d, unlocking mutex\n",
       my_id, count);
...
}

void* thread_handler1(){
... // waits till the previous thread has finished counting
pthread_mutex_lock(&count_mutex);
while (count<COUNT_LIMIT) {
   pthread_cond_wait(&count_threshold_cv, &count_mutex);
   printf("watch_count(): thread %ld Condition signal received.\n", my_id);
}
pthread_mutex_unlock(&count_mutex);
pthread_exit(NULL);
}
void*线程处理程序(){
…//在达到计数限制之前计数
如果(计数==计数\u限制){
pthread_cond_信号(&count_threshold_cv);
printf(“inc_count():已达到线程%ld,计数=%d阈值。\n”,
我的身份证,伯爵);
}
printf(“inc_count():线程%ld,计数=%d,解锁互斥锁\n”,
我的身份证,伯爵);
...
}
void*thread_handler1(){
…//等待上一个线程完成计数
pthread_mutex_lock(&count_mutex);
而
输入thread\u handler1并执行cond\u wait。从手册页中我了解了
这个cond_wait将立即以原子方式释放锁。那么为什么会这样呢
他们在下面的螺纹手柄1中再次释放锁

因为应该等待的线程在调用
wait
时会释放锁,但在收到信号后(当它可用时)会重新获取锁。这就是为什么以后需要显式地重新释放它

第一个线程满足条件并达到条件后 信号我期望阻塞的线程执行其步骤。 相反,我在执行 cond_信号为什么会这样


因为调用
信号
不会从CPU切换线程。它将继续正常运行。

对于2),还请注意,调用
pthread\u signal
并不会释放您先前获得的锁。因此,等待的线程无法重新启动处理,直到信令线程调用
pthread\u unlock
。非常感谢您的回复。您能解释一下为什么线程以后必须执行显式pthread\u unlock吗?我没有回答能够理解答案。@CHID:你是说问题1吗?是的,Tudor。
因为应该等待的线程在调用wait时会释放锁,但在收到信号时会重新获取锁。这就是为什么你以后需要显式地重新释放它。
更具体地说,没有pthread\u锁。而被阻塞的线程“不需要立即安排"因为发出信号的线程将执行自己的任务。这不会产生竞争条件吗?@CHID:发生的情况是线程等待并释放锁。但是在收到继续的信号后,在重新获取锁之前,不允许继续执行。因此,一旦锁再次可用,它将重新获取锁,继续正在执行,但完成后需要释放。请注意,无论何时修改
count
,互斥锁都应锁定,并且通常应一直保持到调用
pthread\u cond\u signal
为止。即,顺序为:锁定、修改、信号(如果“准备就绪”),unlock.@williamorris:如果您不需要阻止新的服务员在发信号之前到达,您可以在调用
pthread\u cond\u signal
之前解锁互斥锁,从而获得更好的性能(减少上下文切换和/或减少到内核空间的往返次数)@R..:保持互斥锁始终有效,无论其他线程上的活动性质如何。只有当这些信令事件频繁发生时,性能才是一个问题。您提出的性能问题是否与实现试图唤醒服务员的确切时间有关?如果它试图在信号传递后立即唤醒显然它不能(因为信号员仍然有互斥)-这可能会对性能造成轻微影响。但是,如果实现等待直到释放互斥体,那么是否存在性能差异?在Linux上,在互斥体被锁定时发送信号不会唤醒服务员,而是会使用一个特殊的futex命令将服务员重新加入互斥体,而不是条件变量。但是,这然后,当您随后解锁互斥锁以唤醒服务生时,需要第二次系统调用,即额外往返到kernelspace。如果互斥锁已解锁,则信号可以直接唤醒服务生,并且只需要往返到kernelspace一次。在缺少“requeue”的实现上像Linux这样的命令,区别应该更严重:服务员实际上会被叫醒,然后立即在互斥锁上再次阻塞。我没有测量这两种实现类型的性能差异,但假设(这通常是真的)所花费的时间主要由系统调用控制,仅使用一个系统调用而不是两个系统调用应该是一个可测量的性能增益。