R..*_*R.. 6 c posix fork pthreads
标准用法pthread_atfork应该是在 pre-fork 处理程序中获取所有锁,并在父处理程序和子处理程序中释放它们。然而,据我所知,这是不可能的。pthread_mutex_unlock如果调用线程不是互斥锁的所有者,则指定为具有未定义的行为(在正常或默认类型互斥锁的情况下)或失败(在递归或错误检查互斥锁的情况下)。并且在注册的子处理程序中pthread_atfork,调用线程是新创建进程的主线程,因此不能是互斥锁的所有者。
是我弄错了还是整个pthread_atfork习语被设计破坏了并且基本上无法使用?
编辑:我也没有看到针对该问题的任何有效(便携式)解决方法。理想情况下,可以在子进程中销毁并重新初始化互斥锁,除了调用pthread_mutex_destroy已初始化的互斥锁被指定为未定义行为,以适应其中互斥锁不是 POD 但涉及对某些内核级对象的引用的荒谬实现。
小智 1
我认为这是来自 man 的相关文本:
当调用 fork() 时,只有 调用线程会在子进程中复制。同步变量在子级中保持与调用 fork() 时在父级中相同的状态。因此,例如,互斥锁可能由子进程中不再存在的线程持有,并且任何关联的状态可能不一致。父进程可以通过显式代码通过 pthread_atfork() 获取和释放对子进程至关重要的锁来避免这种情况。此外,任何关键线程都需要在子级中重新创建并重新初始化为正确的状态(也通过 pthread_atfork())。
在子进程中执行 atfork 处理程序的线程是在父进程中执行 atfork 准备处理程序的线程的精确副本,因此有权解锁互斥体。