Tag: ice

如何使用pthread_atfork()和pthread_once()重新初始化子进程中的互斥锁

我们有一个C ++共享库,它使用ZeroC的Ice库来实现RPC,除非我们关闭Ice的运行时,否则我们观察到子进程挂在随机互斥锁上。 Ice运行时启动线程,具有许多内部互斥锁并保持打开文件描述符到服务器。 另外,我们有一些我们自己的互斥体来保护我们的内部状态。 我们的共享库被数百个内部应用程序使用,因此我们无法控制进程何时调用fork(),因此我们需要一种方法来安全地关闭Ice并在进程分叉时锁定我们的互斥锁。 在pthread_atfork()上读取处理互斥锁和内部状态的POSIX标准: 或者,某些库可能只能提供一个子例程,它将库中的互斥锁和所有关联状态重新初始化为某个已知值(例如,最初执行映像时的状态)。 但是,这种方法是不可能的,因为如果互斥锁或锁仍然被锁定,则允许实现失败* _init()和* _destroy()调用互斥锁和锁。 在这种情况下,子例程无法重新初始化互斥锁和锁。 在Linux上,此测试C程序从子pthread_atfork()处理程序中的pthread_mutex_unlock()返回EPERM。 Linux需要将_NP添加到PTHREAD_MUTEX_ERRORCHECK宏以便进行编译。 这个程序是从这个好的线程链接的。 鉴于解锁或破坏子代中的互斥锁在技术上是不安全或合法的,我认为最好有指向互斥锁的指针,然后让孩子在堆上创建新的pthread_mutex_t并让父项的互斥量单独使用,从而拥有小内存泄漏。 唯一的问题是如何重新初始化库的状态,我正在考虑重新设置pthread_once_t。 也许是因为POSIX有一个pthread_once_t的初始化程序,它可以重置为初始状态。 #include #include #include static pthread_once_t once_control = PTHREAD_ONCE_INIT; static pthread_mutex_t *mutex_ptr = 0; static void setup_new_mutex() { mutex_ptr = malloc(sizeof(*mutex_ptr)); pthread_mutex_init(mutex_ptr, 0); } static void prepare() { pthread_mutex_lock(mutex_ptr); } static void parent() { pthread_mutex_unlock(mutex_ptr); } static void child() […]