我正在使用生产者和消费者线程的Linux应用程序。 这是一个相当成熟的应用程序,我不想更改比我更多的架构。
生产者和消费者线程通过等待队列链接。 这是一个通过std :: queue和一个条件variables和互斥体一起实现的类。
现在,我希望消费者线程能够fork / exec一个subprocess,并等待subprocess完成,或等待队列非空,以先发生者为准。 如果等待队列不是空的,则必须终止subprocess。 编辑:subprocess是无法更改的第三方应用程序。
一种可能性是在subprocess终止时对我的条件variables调用pthread_cond_signal(),但是如何实现呢? 我不能使用SIGCHLD的处理程序,至less不能直接使用,因为手册页说pthread_cond_signal()不能在信号处理程序中使用。
一种可能的方法是产生subprocess,然后启动一个线程到一个阻塞的waitpid(),最后是pthread_cond_signal()。 但是,这看起来有点笨重:我真的需要产生一个线程来保持一个pid?
对于混合waitpid和select/民意调查/ epoll有自我pipe道技巧 。 是否有任何混合waitpid和条件variables的等价物?
注1:在某些实现中,SIGCHLD中断条件variables等待函数。 这不是可移植的,如果可能的话,我宁愿不要依赖这种行为。
注2:由于条件variables被封装在等待队列类中,所以我需要扩展这个类来允许应用程序发出互斥信号。 这只是我在问题中掩盖的一个微不足道的实现细节。
也许这个工作,但我不知道:
创建一个信号量,它将被注册在你的等待队列中,并且每当等待队列本身要改变它自己的锁以便指示状态的改变时,锁定/改变/解锁。 当它持有信号量时,你应该改变它自己的互斥量。
为SIGCHLD实现信号处理程序,然后在第三方应用程序终止时执行信号锁定/更改/解锁,如果情况不是这样,则不执行任何操作。
在上面的例子中,他们会等待1,然后在您的信号量上增加(作为一个信号操作),当他们想要获得信号量锁时,然后完成他们的工作,然后将信号量改为0 (递减2)解锁它为您的等待线程。 这样,你不会有任何队列/第三方应用程序连续两个成功的锁。
在你的实际线程中,这应该是等待第三方应用程序终止或等待队列,你基本上等待在同一个信号等待0锁(和递减,如果有其他的服务员等待0)。 如果获取锁,则检查您的等待队列上的互斥锁是否已释放。 如果没有,你知道你的第三方应用程序终止。 你执行你的工作,然后通过增加你的信号量到1 ,从而解锁你的队列和第三方应用程序的信号量。
由于semop(2) -lock调用可以被信号处理程序中断,所以你必须检查EINTR并且循环你所有的锁定。
如果确保信号处理程序将完成它的执行(我认为是这样),这可能会起作用。