Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.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 sem_wait未按预期工作?_C_Synchronization_Pthreads_Semaphore - Fatal编程技术网

C sem_wait未按预期工作?

C sem_wait未按预期工作?,c,synchronization,pthreads,semaphore,C,Synchronization,Pthreads,Semaphore,我上一个问题的后续问题: 我将代码改为使用信号量,而不是互斥锁和条件信号。然而,我似乎遇到了无法解释的情况 这是摘要 function thread work { while (true) sem_wait(new_work) if (condition to exit){ exit } while (work based condition){ if (condition to exit) exit d

我上一个问题的后续问题:

我将代码改为使用信号量,而不是互斥锁和条件信号。然而,我似乎遇到了无法解释的情况

这是摘要

function thread work {
   while (true)
   sem_wait(new_work)
   if (condition to exit){
      exit
      }
   while (work based condition){
      if (condition to exit)
         exit
      do work
      if (condition to exit){
      exit
      }
   sem_post(work_done)
   set condition to ready
   }
exit
}

function start_thread(){
sem_wait(work_done)
setup thread work
create work
sem_post(new_work)
return to main()
}

function end_thread(){
set condition to exit
sem_post(new_work)
pthread_join(thread)
clean up
}
控制流程说明: 主线程调用start_thread来创建一个线程,并移交一些工作。主要和工人继续并行。main可以在工人之前完成其工作,反之亦然。若main在工作人员之前完成其工作,则工作人员不再有效,必须被告知中止其工作。这是“退出条件”。此函数(start_thread)不会在每次调用时创建线程,而是在第一次调用时创建。它更新的其余时间对线程有效

线程被重用并提供新的工作参数,以减少创建和销毁线程的开销。一旦主线程决定不再需要工作线程,它将调用end_线程函数。这个函数将告诉线程不再需要它,等待它退出,然后清理指针、信号量和工作结构

线程在开始工作之前总是等待信号量(new_work)。我正在使用sem new_work向线程发出信号,新的工作现在可用,应该开始了。线程向控制函数(start_thread)发出信号,表示它已使用信号量work_done完成/中止工作

除了一些随机情况外,一切都很顺利。end_线程正在pthread_join处等待,线程正在sem_wait(new_work)处等待

“退出条件”由互斥锁保护

我似乎不知道是什么导致了这种情况

这里是跟踪的输出

 thread 1: sem NEW count, before wait : 0
 thread 1: sem NEW count, before wait : 0
 end post: sem NEW count, before post : 0
 end post: sem NEW count, after post : 1
 thread 1 exit.
 thread exited, cleanup 1

 Entered initialization for thread: 2

 created a thread: 2
 thread: 2 started.

.....


 thread 2: sem NEW count, before wait : 0
 thread 2: sem NEW count, before wait : 0
 thread 2: sem NEW count, before wait : 0
 end post: sem NEW count, before post : 0
 thread 2 exit.
 end post: sem NEW count, after post : 0
 thread exited, cleanup 2

 Entered initialization for thread: 3

 created a thread: 3
 thread: 3 started.

 .....

 thread 3: sem NEW count, before wait : 0
 thread 3: sem NEW count, before wait : 0
 end post: sem NEW count, before post : 0
 end post: sem NEW count, after post : 1
 thread 3: sem NEW count, before wait : 0
此时,线程正在信号灯处等待,而exit_线程正在pthread_join处等待


感谢您的时间。

扫描电镜上的POSIX函数可以被信号中断,因此它们会被进程/线程可能收到的任何信号中断,特别是由于IO

  • 始终调查返回值 系统调用的数量(一般不限于
    sem\u等待
  • 特别是将
    sem\u wait
    放入 循环时,检查是否有错误 条件如果错误条件为 EINTR重新运行
    sem\u wait

这同样适用于其他
sem
功能。查找它们的特定错误条件并进行特定处理。

我发现了错误。我正在测试互斥锁外部的条件,并更改互斥锁内部条件的值。由于调度的随机性,主线程和工作线程可能同时竞争锁,并且都会改变条件的值。根据上次更改条件值的线程,工作线程将在其应该退出时继续。两人都在sem_等待一个永远不会出现的帖子。工作线程等待新工作,而主线程等待工作线程退出,因为它已将条件设置为退出

我将测试移到互斥锁内部,现在可以正常工作了

下面是修改后的代码片段

    }
   sem_post(work_done)
   enter mutex lock
   test condition
       set condition to ready if test is satisfied
   exit lock
   }