Linux 上的執行緒是作為程序實現的嗎?
我正在閱讀這本書,Mark Mitchell、Jeffrey Oldham 和 Alex Samuel 合著的 Advanced Linux Programming。2001年的,有點老了。不過我覺得還是蠻不錯的。
但是,我發現它與我的 Linux 在 shell 輸出中產生的結果有所不同。在第 92 頁(查看器中的 116),第 4.5 章 GNU/Linux 執行緒實現以包含以下語句的段落開頭:
GNU/Linux 上 POSIX 執行緒的實現與許多其他類 UNIX 系統上的執行緒實現有一個重要的不同:在 GNU/Linux 上,執行緒被實現為程序。
這似乎是一個關鍵點,稍後用 C 程式碼說明。書中的輸出是:
main thread pid is 14608 child thread pid is 14610
在我的 Ubuntu 16.04 中是:
main thread pid is 3615 child thread pid is 3615
ps
輸出支持這一點。我想從 2001 年到現在,一定發生了一些變化。
下一頁的下一個小節,4.5.1 信號處理,建立在前一個語句的基礎上:
信號和執行緒之間的互動行為因一個類 UNIX 系統而異。在 GNU/Linux 中,行為是由執行緒作為程序實現的這一事實決定的。
看起來這在本書後面會變得更加重要。有人可以解釋這裡發生了什麼嗎?
我看過這個Linux 核心執行緒真的是核心程序嗎?,但這並沒有多大幫助。我很困惑。
這是C程式碼:
#include <pthread.h> #include <stdio.h> #include <unistd.h> void* thread_function (void* arg) { fprintf (stderr, "child thread pid is %d\n", (int) getpid ()); /* Spin forever. */ while (1); return NULL; } int main () { pthread_t thread; fprintf (stderr, "main thread pid is %d\n", (int) getpid ()); pthread_create (&thread, NULL, &thread_function, NULL); /* Spin forever. */ while (1); return 0; }
clone(2)
我認為手冊頁的這一部分可能會清除差異。PID:CLONE_THREAD(自 Linux 2.4.0-test8 起)
如果設置了 CLONE_THREAD,則子程序與呼叫程序位於同一執行緒組中。
執行緒組是 Linux 2.4 中添加的一項功能,用於支持共享單個 PID 的一組執行緒的 POSIX 執行緒概念。在內部,這個共享的 PID 是執行緒組的所謂執行緒組標識符 (TGID)。從 Linux 2.4 開始,呼叫 getpid(2) 返回呼叫者的 TGID。
“執行緒被實現為程序”片語是指執行緒過去具有單獨的 PID 的問題。基本上,Linux 最初在程序中沒有執行緒,只有可能擁有一些共享資源(如虛擬記憶體或文件描述符)的單獨程序(具有單獨的 PID)。
CLONE_THREAD
並且程序 ID (*)和執行緒 ID 的分離使得 Linux 行為看起來更像其他系統,並且在這個意義上更像 POSIX 要求。儘管從技術上講,作業系統仍然沒有執行緒和程序的單獨實現。信號處理是舊實現的另一個問題領域,這在@FooF在他們的答案中引用的論文中有更詳細的描述。
正如評論中所指出的,Linux 2.4 也於 2001 年發布,與本書同年發布,因此該消息沒有發表也就不足為奇了。