Linux

Linux 上的執行緒是作為程序實現的嗎?

  • April 27, 2020

我正在閱讀這本書,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 年發布,與本書同年發布,因此該消息沒有發表也就不足為奇了。

引用自:https://unix.stackexchange.com/questions/364660