Waitpid and pthread_cond_wait (3)

I am working on a Linux application that uses streams of manufacturers and consumers. This is a fairly mature program, and I do not want to change the architecture more than necessary.

Production and consumer flows are linked through the expected lineup. This is a class implemented through std :: queue along with the variable condition and mutex.

Now I want consumer threads to be able to process the fork / exec child process and wait for the child process to complete, or the expected queue is not empty, whichever happens first. If the expected queue is not empty, then the child process must be killed. Edit:. Child processes are third-party applications that cannot be changed.

One possibility is to call pthread_cond_signal () in my condition variable when the child process exits, but how to do it? I cannot use the handler for SIGCHLD, at least not directly, because the man page says that pthread_cond_signal () cannot be used from the signal handler.

One possible way is to create a child process, and then start the thread to block waitpid () and finally pthread_cond_signal (). This seems a bit awkward: do I really need to spawn a thread to keep an eye on pid?

For mixing waitpid and select / poll / epoll there is Trick Trick . Is there an equivalent for mixing waitpid and variable conditions?

Note 1: In some implementations, SIGCHLD interrupts state variable wait functions. This is not portable, and if possible, I would rather not rely on this behavior.

Note 2: Since the condition variable is encapsulated in the wait queue class, I need to extend this class so that the application can signal the mutex. This is just a trivial implementation detail that I was silent about in my question.

+6
source share
1 answer

Maybe this works, but I'm not sure:

Create a semaphore that will be registered in your queue and locked / changed / unlocked whenever the queue itself changes its own lock to indicate a state change. You must change its own mutex while it holds the semaphore.

Implement a signal handler for SIGCHLD , which will then perform semaphore locking / changing / unlocking when a third-party application terminates and does nothing if it is not.

In the above cases, they will wait 1 and increment (as one semaphore operation) on your semaphore, when they want to acquire a semaphore lock, then do their job, and then change the semaphore to 0 (decrementing 2) to unlock it for your waiting thread. This way you will not have two successful locks from any of the queues / third-party applications.

In your actual thread, which should either wait for the third-party application to finish, or your expected queue, you are basically forced to wait for a lock on the same semaphore, waiting for 0 (and decreasing it if there are other waiters by 0). If a lock is received, you check to see if the mutex in your queue is freed. If not, you know that your third-party application has been discontinued. You do your work, and then change your semaphore to 1, increasing it and thereby open the semaphore again for your queue and third-party application.

Since the call to semop(2) -lock can be intercepted by signal handlers, you will need to check the EINTR and make any lock attempt that you have.

This probably works if it is guaranteed that the signal handler will complete the execution (from which I think it is).

+1
source

Source: https://habr.com/ru/post/924731/


All Articles