涉及__unregister_atfork和TCMalloc的程序死锁

问题描述 投票:2回答:1

请考虑以下C ++程序。我希望第一个调用exit的线程将终止该程序。这是我用g++ -g test.cxx -lpthread编译时发生的情况。但是,当我链接到TCMalloc(g++ -g test.cxx -lpthread -ltcmalloc)时,它挂起了。 为什么?

检查堆栈帧表明,第一个调用exit的线程被卡在__unregister_atfork中,等待某种类型的引用计数变量达到0。由于它先前获取了互斥量,因此所有其他线程都死锁了。我的猜测是在tcmalloc的tforalloc的atfork处理程序和我的代码之间存在某种交互。

[使用gperftools 2.0在CentOS 6.4上测试。

$ cat test.cxx
#include <unistd.h>
#include <iostream>
#include <pthread.h>
#include <stdlib.h>

using namespace std;

static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

static void* task(void*) {
    if (fork() == 0)
        return NULL;

    pthread_mutex_lock(&m);
    exit(0);
}

int main(int argc, char **argv) {
    cout << getpid() << endl;

    pthread_t t;
    for (unsigned i = 0; i < 100; ++i) {
        pthread_create(&t, NULL, task, NULL);
    }

    sleep(9999);
}

$ g++ -g test.cxx -lpthread && $ ./a.out 
19515

$ g++ -g test.cxx -lpthread -ltcmalloc && ./a.out                             
24252
<<< process hangs indefinitely >>>
^C

$ pstack 24252
Thread 101 (Thread 0x7ffaabdf7700 (LWP 24253)):
#0  0x000000328c4f84c4 in __unregister_atfork () from /lib64/libc.so.6
#1  0x00007ffaac02d2c6 in __do_global_dtors_aux () from /usr/lib64/libtcmalloc.so.4
#2  0x0000000000000000 in ?? ()
Thread 100 (Thread 0x7ffaab3f6700 (LWP 24254)):
#0  0x000000328cc0e054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1  0x000000328cc09388 in _L_lock_854 () from /lib64/libpthread.so.0
#2  0x000000328cc09257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3  0x0000000000400abf in task(void*) ()
#4  0x000000328cc07851 in start_thread () from /lib64/libpthread.so.0
#5  0x000000328c4e894d in clone () from /lib64/libc.so.6
<<< the other 98 threads are also deadlocked >>>
Thread 1 (Thread 0x7ffaabdf9740 (LWP 24252)):
#0  0x000000328c4acbcd in nanosleep () from /lib64/libc.so.6
#1  0x000000328c4aca40 in sleep () from /lib64/libc.so.6
#2  0x0000000000400b33 in main ()

EDIT:我认为问题可能是exit不是线程安全的。根据POSIXexit是线程安全的。但是,glibc documentation指出exitnot线程安全的。

c++ multithreading pthreads fork tcmalloc
1个回答
0
投票

我也遇到了同样的问题,现在有解决方案吗?thx

© www.soinside.com 2019 - 2024. All rights reserved.