2017-01-13 134 views
5

我正在閱讀Silberschatz第7版的Operating System Concepts,它說同一進程的線程共享代碼段,數據段和其他O.S.資源,但具有單獨的堆棧和寄存器組。但是,我正在處理的問題集表明線程共享局部變量,但不是存儲在堆棧中的局部變量,因此各個線程應該有自己的副本?線程是否共享局部變量?

+0

'問題集'可能是錯誤的或使用不好的術語,很難說。你能發表有意義的報價嗎? –

+0

但是:不,線程不共享真正的本地變量。但是在C#中,一個局部變量可能會被捕獲或「關閉」,然後它變成另一個故事。 –

回答

7

Threads通常共享以下內容。

  1. 數據段(全局變量,靜態數據)
  2. 地址空間。
  3. 代碼段。
  4. I/O,如果文件處於打開狀態,所有線程都可以讀取/寫入。
  5. 父進程ID。
  6. 的堆

threads維護自己的stack副本,局部變量都存儲在堆棧上這樣啊,你是正確的,每個線程都應該有自己的局部變量的副本。

可能是它使用的一個不好的術語,也可能是它的特定問題集。

+0

Silberschatz使用的術語當然是由該地區的專業人士修改的。幾乎不好。 –

1

我讀過單個進程可以有多個線程。 同一進程的多個線程在它們之間共享事物。如果你想知道他們分享什麼,不知道什麼。考慮到進程由地址空間,堆棧,堆,全局變量,代碼,數據,OS資源組成,它們之間由線程共享的是什麼?我有以下猜測:

全局變量 - 我已閱讀線程共享全局變量。同時,在Java和C#編程時,我已經創建線程來共享 級別的變量。所以我相信這些線程共享全局變量(雖然不確定高級編程語言中的概念是否轉化爲低操作系統級別的事實)。

- 由於全局變量存儲在堆中,因此堆被線程共享。

堆棧 - 因爲每個線程都可以有自己的執行順序/代碼,就必須有自己的堆棧,它可能會推/流行 其程序計數器的內容(當說函數調用和返回 發生)。所以同一進程的線程不共享堆棧。現在我 不確定以下事情的共享

地址空間 - 不知道地址空間下的究竟是什麼。但我猜想地址空間通常用於 進程的上下文中,而不是線程。並且因爲所有相同進程的線程都駐留在與父進程相同的地址空間中,所以 塊引用 線程共享地址空間。 (但是,他們在同一地址空間內維護不同的堆棧 ?)

操作系統資源 - 我想這可能是非常具體的實現。例如,父進程可以選擇性地將相同文件的句柄賦給 的一些線程,而不是全部。或者我錯了,操作系統資源 意味着文件以外的東西?

代碼 - 線程可以有不同的代碼,所以共享代碼並不總是這種情況。

數據 - 不確定在數據下需要考慮什麼。但確保全局變量在線程間共享。並確保本地 變量沒有類似的共享。總的來說,我很困惑 由於含糊不清的條款,在操作 完成的超級概括在線提供的系統書籍和額外實施細節 。所以我想找到一些可以滿足我的答案。

所以我來得出這樣的結論,線程維護自己的堆棧,和局部變量都存儲在堆棧上,所以可能在線程局部變量是不可能的共享。

0

進程內的線程共享相同的地址空間。

「變量」是一種編程語言的概念。當源代碼通過編譯器時,變量消失(有些可能會減少爲符號)。

線程可以絕對共享所有內存。一個線程可以訪問另一個線程的內存位置。

完成此操作的難易程度取決於編程語言和基礎鏈接器支持。有幾種編程語言具有真正的線程支持(例如,Ada稱爲文本)。 Ada有明確的機制允許線程使用變量共享數據。

那麼接下來:

我被Silberschatz 7版閱讀操作系統的概念,

那是你的問題的開始。

它表示同一進程的線程共享代碼段,數據段和其他O.S.資源,

有所有系統特定的概念。在許多系統中,不存在「代碼段」和「數據段」。只有具有特定屬性的內存(例如,只讀,讀/寫,讀/執行)。

但是具有單獨的堆棧和寄存器組。

寄存器是在調度線程時分配的系統資源。一個線程沒有自己的一組寄存器。每個線程都有自己獨特的一組寄存器值,它們在線程處於活動狀態時加載,並在線程變爲非活動狀態時保存。

堆棧只是讀/寫內存塊。

但是,我正在處理的問題集表示線程共享局部變量,但不是存儲在堆棧上的局部變量,因此各個線程應該有自己的副本?

同樣,線程共享內存。只有當使用的編程語言支持這種共享或者這種共享是由「事故」發生時,它們才共享「本地」變量。

變量映射到內存分配類型的用法是編譯器的一個功能。 FORTRAN 66/77和COBOL通常沒有在堆棧上分配任何變量

0

符合POSIX標準的OS的線程必須共享局部變量(又名自動變量)。從卷XBD,基本定義,第3章,定義,輸入3.404,在Open Group Base Specifications Issue 7的線程(在回答時):

任何其地址可以由一個線程來確定,包括但不限於靜態變量,通過malloc()獲得的存儲,通過實現定義的函數獲得的直接可尋址存儲以及自動變量,都可以在同一個進程中訪問所有線程。

下面的代碼,具有輸出10,應該足夠用於舉例說明我的權利要求,如果假設靜態變量確實線程之間共享:

#include <pthread.h> 
#include <unistd.h> 
#include <stdio.h> 

static int* shared_pointer = NULL; 

void* alter_thread_entry(void* arg) { 
    // The following variable will be reachable, 
    // while it exists, by both the main and the alter thread. 
    int local_variable = 10; 
    shared_pointer = &local_variable; 
    sleep(2); 
    return 0; 
} 

int main() { 
    pthread_t alter_thread; 
    pthread_create(&alter_thread, NULL, alter_thread_entry, NULL); 
    sleep(1); 
    printf("%i", *shared_pointer); 
    fflush(stdout); 
    pthread_join(alter_thread, NULL); 
} 

調用堆棧該跡線的控制執行線程是一個進程的線程之間不共享的線程。然而,這一點是依賴於實現的,因爲在前述標準中沒有確定它。