Linux 上克隆线程后 fclose 挂起

发布于 2025-01-04 12:34:46 字数 1038 浏览 2 评论 0 原文

当对全局文件描述符调用 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 内部的一些互斥体。

Backtrace:

#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() 和设置线程本地存储。

谢谢!

When calling fclose on the global file descriptor, the program hang.

It happened after exits of several threads created by clone.

Below is the sequence:

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);

Non thread deals with fid.

From strace, the program hang in futex waiting for "main_arena". I think this should be some mutex inside glibc.

Backtrace:

#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

This happens on Linux with glibc 2.5, but not on Linux with glibc 2.12.

I am wondering whether it is because we cannot create threads using clone() like this. In NPTL, lots of more things are done, such as set_robust_futex() and seting thread local storage.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

﹎☆浅夏丿初晴 2025-01-11 12:34:46

我无法想象你会期望它如何运作。 stdio 库在内部使用锁。锁特定于所使用的线程模型。您正在使用自己的线程模型,但期望 stdio 库的锁能够神奇地与其一起工作。这显然不是一个合理的期望。

I can't imagine how you would expect this to work. The stdio library uses locks internally. Locks are specific to the threading model being used. You are using your own threading model, but expecting the stdio library's locks to magically work with it. That's clearly not a reasonable expectation.

沉溺在你眼里的海 2025-01-11 12:34:46

你的内核版本是什么?

这似乎是一个内核错误。

请参阅 futex_wait 错误内核补丁了解更多信息。

What is your kernel version?

It seems a kernel bug.

see futex_wait bug and kernel patch for more information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文