gpt4 book ai didi

c++ - 大多数时候从 POSIX 线程在 C++ 中打开/proc/net/tcp 失败

转载 作者:IT王子 更新时间:2023-10-29 00:31:13 26 4
gpt4 key购买 nike

当我尝试从 C++ 中的子 POSIX 线程打开/proc/net/tcp 时,它失败并显示“没有这样的文件或目录”错误。如果我尝试从父线程打开它,它每次都会成功,而在父线程中打开/关闭它的过程也会使它在子线程中成功大约三分之一的时间。我可以 100% 地在子线程中打开/proc/uptime 而不会出现问题。下面是一些可以用“g++ -Wall test.cc -o test -pthread”编译的示例代码:

#include <iostream>
#include <fstream>
#include <cstring>
#include <cerrno>
#include <pthread.h>

using namespace std;

void * open_test (void *)
{
ifstream in;
in.open("/proc/net/tcp");
if (in.fail())
cout << "Failed - " << strerror(errno) << endl;
else
cout << "Succeeded" << endl;
in.close();

return 0;
}

int main (int argc, char * argv[])
{
open_test(NULL);

pthread_t thread;
pthread_create(&thread, NULL, open_test, NULL);
pthread_exit(0);
}

我在 Ubuntu 12.04 机器上运行它,在 Linux 内核 3.2.0 上配备 Intel i5-2520M(2 核 * 2 虚拟核)。这是我连续运行 6 次上述代码的输出:

mike@ung:/tmp$ ./test
Succeeded
Failed - No such file or directory
mike@ung:/tmp$ ./test
Succeeded
Succeeded
mike@ung:/tmp$ ./test
Succeeded
Failed - No such file or directory
mike@ung:/tmp$ ./test
Succeeded
Failed - No such file or directory
mike@ung:/tmp$ ./test
Succeeded
Succeeded
mike@ung:/tmp$ ./test
Succeeded
Failed - No such file or directory
mike@ung:/tmp$

可能值得注意的是,如果我使用 fork 而不是 posix 线程,我就不会遇到这个问题。如果我使用 fork,那么子进程读取/proc/net/tcp 没有问题

只需输入几个数据点...。看起来这是 Linux 中的倒退,因为 2.6.35 似乎在 100% 的时间内都可以正常工作。 3.2.0 大部分时间都在呕吐,即使是在我基于 Pentium M 的慢速旧笔记本电脑上也是如此。

最佳答案

正如 scott 在他的回答中指出的那样,添加 pthread_join(thread, NULL) 可以解决问题。但是为什么?

我们把程序放到gdb中,在打开失败的地方设置断点:

(gdb) break test.cc:14
Breakpoint 1 at 0x400c98: file test.cc, line 14.

然后我们可以观察到两种不同类型的行为:

  1. (gdb) run […]
    Succeeded
    [New Thread 0x7ffff7fd1700 (LWP 18937)] // <- child thread
    [Thread 0x7ffff7fd3740 (LWP 18934) exited] // <- parent thread
    [Switching to Thread 0x7ffff7fd1700 (LWP 18937)]
    Breakpoint 1, open_test () at test.cc:14
  2. (gdb) run
    Succeeded
    [New Thread 0x7ffff7fd1700 (LWP 19427)] // <- child thread
    Succeeded
    [Thread 0x7ffff7fd1700 (LWP 19427) exited]
    [Inferior 1 (process 19424) exited normally]

第一个建议父进程在子进程之前退出。与在 Linux 上一样,进程和线程几乎相同,这意味着与主进程关联的 PID 已被清理。没有什么能阻止子线程运行。它和他的 pid 仍然完全有效。只是/proc/self指向主进程的PID,此时已被删除。

关于c++ - 大多数时候从 POSIX 线程在 C++ 中打开/proc/net/tcp 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11580020/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com