sem_wait没有按预期工作?

时间:2010-09-07 19:11:35

标签: c synchronization pthreads semaphore

跟我提出问题: Conditional wait with pthreads

我将代码更改为使用信号量而不是互斥锁和条件信号。但是,我似乎陷入了无法解释的状况。

这是摘要

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_thread函数。此函数将告诉线程它不再需要,等待它退出然后清除指针,信号量和工作结构。

在开始工作之前,线程将始终等待信号量(new_work)。我正在使用sem new_work来通知线程现在可以使用新工作并且应该启动它。线程使用信号量work_done向控制功能(start_thread)发出信号,表示它已完成/中止了工作。

除了在一些随机情况下,一切都很好。 end_thread正在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_thread正在pthread_join等待。

感谢您的时间。

2 个答案:

答案 0 :(得分:3)

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

  • 始终调查返回值 系统调用(通常不仅适用于 sem_wait
  • 特别将sem_wait放入 while循环,检查错误 条件。如果错误条件是 EINTR重新运行sem_wait

同样适用于其他sem_函数。查看它们的特定错误情况并特别处理它们。

答案 1 :(得分:0)

我发现了这个错误。我正在测试互斥锁之外的条件并更改互斥锁内的条件值。通过调度的随机性,可能发生主线程和工作线程可以同时竞争锁并且都改变条件的值。根据哪个线程最后更改了条件的值,工作线程将在其应该退出时继续。两者都在sem_wait等待一个永远不会到来的帖子。当主线程等待工作人员退出时,worker等待新工作,因为它已经设置退出条件。

我将测试移到互斥锁内,现在工作正常。

以下是修改后代码的片段

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