這裡行為似乎是 /proc 虛擬 文件系統 中的一種 Bug 。 如果在打開 file: 之前添加這裡代碼system("ls -l/proc/net/proc/self/net/tcp");
你將看到 /proc/net 是指向 /proc/self/net的符號鏈接,而 /proc/sec/net/tcp 在對 open_test的調用中被正確列出,即使生成的線程調用失敗。
對這個測試的我剛剛認識到上面的測試是假的,因為自我將引用系統調用的進程,而不是這個過程。 使用以下函數還可以顯示 Bug:void ls_command () {
ostringstream cmd;
cmd <
<
<
<
<
system(cmd.str().c_str());
}
你將看到,生成的線程有時無法看到父文件的/net/tcp 文件。 實際上它已經消失了,因為這是運行 ls 命令的shell的衍生進程。
下面的解決方法允許子線程可靠地訪問它的/proc/net/tcp 。
我的理論是,它是一種比賽條件 Bug,正確設置線程的/proc/self 條目作為父狀態和線程特定狀態的混合。 作為測試和工作,我使用 open_test 代碼來使用與線程關聯的"進程標識符",而不是嘗試訪問父( 因為進程 /proc/self 是指父進程 id,而不是線程'。
Edit: 表示,在子線程有機會讀取它之前,Bug 與父進程清理它的/proc/self/... 狀態。 因為子線程仍然是進程的一部分,所以我仍然保持它是一個 Bug 。 它的getpid() 在主線程調用 pthread_exit() 之前和之後仍然是相同的。 父進程的/proc 項應該一直有效,直到所有子線程都完成。 儘管即使儘管
Edit2: argues認為這可能不是一個 Bug 。 作為證據,來自 man proc的是:/proc/[pid]/fd
. . .
In a multithreaded process, the contents of this directory are
not available if the main thread has already terminated (typi-
ally by calling pthread_exit(3)).
但是,在同一個 man 頁麵條目中考慮 /proc/self 條目:/proc/self
This directory refers to the process accessing the/proc file
system, and is identical to the/proc directory named by the
process ID of the same process.
如果相信這不是 Bug,因為線程和進程在Linux中相同,那麼線程應該對 /proc/self 工作有期望。 修改 Bug 可以很容易地修改 /proc/self,以便在 /proc/[getpid] 版本不再可以用時改變 /proc/[gettid] 值。void * open_test (void *)
{
ifstream in;
string file ="/proc/net/tcp";
in.open(file.c_str());
if (in.fail()) {
ostringstream ss;
ss <
cout <
<
file = ss.str();
in.open(file.c_str());
}
if (in.fail())
cout <
else
cout <
in.close();
return 0;
}