How to use pthread_atfork() and pthread_once() to reinitialize mutexes in child processes

后端 未结 2 1681
北恋
北恋 2021-02-02 12:51

We have a C++ shared library that uses ZeroC\'s Ice library for RPC and unless we shut down Ice\'s runtime, we\'ve observed child processes hanging on random mutexes. The Ice r

相关标签:
2条回答
  • 2021-02-02 13:04

    I consider this a bug in the programs calling fork(). In a multi-threaded process, the child process should call only async-signal-safe functions. If a program wants to fork without exec, it should do so before creating threads.

    There isn't really a good solution for threaded fork()/pthread_atfork(). Some chunks of it appear to work, but this is not portable and liable to break across OS versions.

    0 讨论(0)
  • 2021-02-02 13:17

    Congratulations, you found a defect in the standard. pthread_atfork is fundamentally unable to solve the problem it was created to solve with mutexes, because the handler in the child is not permitted to perform any operations on them:

    • It cannot unlock them, because the caller would be the new main thread in the newly created child process, and that's not the same thread as the thread (in the parent) that obtained the lock.
    • It cannot destroy them, because they are locked.
    • It cannot re-initialize them, because they have not been destroyed.

    One potential workaround is to use POSIX semaphores in place of mutexes here. A semaphore does not have an owner, so if the parent process locks it (sem_wait), both the parent and child processes can unlock (sem_post) their respective copies without invoking any undefined behavior.

    As a nice aside, sem_post is async-signal-safe and thus definitely legal for the child to use.

    0 讨论(0)
提交回复
热议问题