在全局文件描述符上调用fclose时,程序挂起。
它是在克隆创建的几个线程退出后发生的。
以下是序列:
FILE * fid = fopen("filename", "w");
...
for(int i=0; i<4; i++){
clone((int (*)(void*))do_work, stack[i], CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|SIGCHLD|CLONE_CHILD_CLEARTID|CLONE_PARENT_SETTID|CLONE_IO, NULL, &(ctid[i]), NULL, &(ctid[i]) );
}
...
fclose(fid);
非线程处理fid。
从strace,程序挂在futex等待“main_arena”。我认为这应该是glibc中的一些互斥。
回溯:
#0 0x0000003f09edf9ee in __lll_lock_wait_private () from /lib64/libc.so.6
#1 0x0000003f09e76d31 in _L_lock_5478 () from /lib64/libc.so.6
#2 0x0000003f09e71c8d in _int_free () from /lib64/libc.so.6
#3 0x0000003f09e7273b in free () from /lib64/libc.so.6
#4 0x0000003f09e60d5b in fclose@@GLIBC_2.2.5 () from /lib64/libc.so.6
这种情况发生在使用glibc 2.5的Linux上,但不适用于使用glibc 2.12的Linux。
我想知道是否因为我们不能像这样使用clone()创建线程。在NPTL中,还有很多工作要做,例如set_robust_futex()和设置线程本地存储。
谢谢!
答案 0 :(得分:0)
我无法想象你会如何期待它的运作。 stdio库在内部使用锁。锁定特定于正在使用的线程模型。您正在使用自己的线程模型,但期望stdio库的锁可以神奇地使用它。这显然不是一个合理的期望。
答案 1 :(得分:0)