天天看點

30、深入了解計算機系統筆記,并發程式設計(concurrent)(2)

1、共享變量

1)線程存儲模型

線程由核心自動排程,每個線程都有它自己的線程上下文(thread context),包括一個惟一的整數線程ID(Thread ID,TID),棧,棧指針,程式計數器,通用目的寄存器和條件碼。每個線程和其他線程一起共享程序上下文的剩餘部分,包括整個使用者的虛拟位址空間,它是由隻讀文本(代碼),讀/寫資料,堆以及所有的共享庫代碼和資料區域組成的,還有,線程也共享同樣的打開檔案的集合。[1]

寄存器從不共享,而虛拟存儲器總是共享。

The memory model for the separate thread stacks is not as clean(整齊清楚的). These stacks are contained in the stack area of the virtual address space, and are usually accessed independently by their respective threads. We say usually rather than always, because different thread stacks are not protected from other threads. So if a thread somehow manages to acquire a pointer to another thread’s stack, then it can read and write any part of that stack. 示例29行中, where the peer threads reference the contents of the main thread’s stack indirectly through the global ptr variable.

2)将變量映射到存儲器

    和全局變量一樣,虛拟存儲器的讀/寫區域隻包含在程式中聲明的每個本地靜态變量的一個執行個體。每個線程的棧都包含它自己的所有本地自動變量的執行個體。

3)我們說變量v是共享的,當且僅當它的一個執行個體被一個以上的線程引用。

示例代碼

2、用信号量同步

當對同一共享變量,有多個線程進行更新時,由于每一次更新,對該變量來說,都有“加載到寄存器,更新之,存儲寫回到存儲器”這個過程,多個線程操作時,便會産生錯位,混亂的情況,有必要對共享變量作一保護,使這個更新操作具有原子性。

信号量s是具有非頁整數值的全局變量,隻能由兩種特殊的操作來處理,稱為P,V操作。

P(s):

  while (s <= 0); s--;

     V (s): s++;

    The P operation waits for the semaphore s to become nonzero, and then decrements it.The V operation increments s.

1)基本思想是,将每個共享變量(或者相關共享變量集合)與一個信号量s(初始值1)聯系起來,然後用P(s),V(s)操作将相應的臨界區(一段代碼)包圍起來。以這種方法來保護共享變量的信号量叫做二進制信号量(binary semaphore),因為值總是1,0。

The definitions of P and V ensure that a running program can never enter a state where a properly initialized semaphore has a negative value.

11.4.4有posix信号量的簡介。

2)二進制信号量通常叫做互斥鎖,在互斥鎖上執行一個P操作叫做加鎖,V操作叫做解鎖;一個已經對一個互斥鎖加鎖而還沒有解鎖的線程被稱為占用互斥鎖。

3、用信号量來排程共享資源

這種情況下,一個線程用信号量來通知另一個線程,程式狀态中的某個條件已經為真了。如生産者-消費者問題。

參考

繼續閱讀