Sim*_*ott 6 c++ linux pthreads
我正在开发一个使用生产者和消费者线程的linux应用程序.这是一个相当成熟的应用程序,我不想更改我的体系结构.
生产者和消费者线程通过可等待的队列链接.这是一个通过std :: queue与条件变量和互斥锁一起实现的类.
现在我希望消费者线程能够分叉/执行子进程,并等到子进程完成,或者等待队列非空,以先发生者为准.如果可等待队列非空,则必须终止子进程.编辑:子进程是无法更改的第三方应用程序.
一种可能性是当子进程终止时在我的条件变量上调用pthread_cond_signal(),但是如何实现呢?我不能使用SIGCHLD的处理程序,至少不能直接使用,因为手册页说pthread_cond_signal()不能从信号处理程序中使用.
一种可能的方法是生成子进程,然后启动一个线程到一个阻塞的waitpid(),最后是pthread_cond_signal().这看起来有点笨拙:我真的需要生成一个线程只是为了关注pid吗?
对于混合waitpid和select/poll/epoll,有Self Pipe Trick.混合waitpid和条件变量有没有相应的东西?
注1:在某些实现中,SIGCHLD中断条件变量等待函数.这是不可移植的,如果可能的话,我宁愿不依赖这种行为.
注意2:由于条件变量封装在可等待的队列类中,我需要扩展此类以允许应用程序发出互斥锁信号.这只是一个简单的实现细节,我在我的问题中掩盖了这一点.
也许这有效,但我不确定:
创建一个信号量,它将在可等待队列中注册,并在可等待队列本身要更改其自己的锁以指示状态更改时锁定/更改/解锁。当它保存信号量时,您应该更改它自己的互斥体。
实现 的信号处理程序SIGCHLD,然后当第 3 方应用程序终止时,它将执行信号量锁定/更改/解锁,如果不是这种情况,则不执行任何操作。
在上述情况下,当他们想要获取信号量锁时,他们将等待1并在信号量上递增(作为一个信号量操作),然后执行其工作,然后将信号量更改为0(递减 2),以便为您的等待线程解锁它。这样您就不会连续从任何队列/第三方应用程序获得两个成功的锁定。
在您的实际线程中,应该等待第 3 方应用程序终止或您的可等待队列,您基本上让它在等待0时等待同一个信号量上的锁(并递减它,如果有其他等待者) 0)。如果获取了锁,则检查可等待队列上的互斥锁是否已释放。如果没有,您就知道您的第 3 方应用程序已终止。您执行工作,然后通过递增将信号量更改为1 ,从而再次解锁队列和第 3 方应用程序的信号量。
由于semop(2)-lock 调用可能会被信号处理程序中断,因此您必须检查EINTR并循环您拥有的任何锁定尝试。
如果保证信号处理程序将完成其执行(我认为是这样),这可能会起作用。