天天看點

Linux多線程實踐(5) --Posix信号量與互斥量解決生産者消費者問題

Posix 信号量

有名信号量

無名信号量

sem_open

sem_init

sem_close

sem_destroy

sem_unlink

sem_wait

sem_post

  與Posix類IPC用法類似: 名字以/somename形式辨別,且隻能有一個/ ,并且總長不能超過NAME_MAX-4 (i.e., 251)。

  Posix有名信号量需要用sem_open 函數建立或打開,PV操作分别是sem_wait 和 sem_post,可以使用sem_close 關閉,删除用sem_unlink。

  有名信号量用于不需要共享記憶體的程序間同步(可以通過名字通路), 類似System V 信号量。

匿名信号量

  匿名信号量隻存在于記憶體中, 并要求使用信号量的程序必須可以通路記憶體; 這意味着他們隻能應用在同一程序中的線程, 或者不同程序中已經映射相同記憶體内容到它們的位址空間中的線程.

  匿名信号量必須用sem_init 初始化,sem_init 函數的第二個參數pshared決定了線程共享(pshared=0)還是程序共享(pshared!=0),也可以用sem_post 和sem_wait 進行操作,在共享記憶體釋放前,匿名信号量要先用sem_destroy 銷毀。

Posix信号量PV操作

  wait操作實作對信号量的減1, 如果信号量計數原先為0則會發生阻塞;

  post操作将信号量加1, 在調用sem_post時, 如果在調用sem_wait中發生了程序阻塞, 那麼程序會被喚醒并且sem_post增1的信号量計數會再次被sem_wait減1;

  互斥鎖是用一種簡單的加鎖方法來控制對共享資源的原子操作。這個互斥鎖隻有兩種狀态,也就是上鎖/解鎖,可以把互斥鎖看作某種意義上的全局變量。在同一時刻隻能有一個線程掌握某個互斥鎖,擁有上鎖狀态的線程能夠對共享資源進行操作。若其他線程希望上鎖一個已經被上鎖的互斥鎖,則該線程就會阻塞,直到上鎖的線程釋放掉互斥鎖為止。可以說,這把互斥鎖保證讓每個線程對共享資源按順序進行原子操作。

  其中,互斥鎖可以分為快速互斥鎖(預設互斥鎖)、遞歸互斥鎖和檢錯互斥鎖。這三種鎖的差別主要在于其他未占有互斥鎖的線程在希望得到互斥鎖時是否需要阻塞等待。快速鎖是指調用線程會阻塞直至擁有互斥鎖的線程解鎖為止。遞歸互斥鎖能夠成功地傳回,并且增加調用線程在互斥上加鎖的次數,而檢錯互斥鎖則為快速互斥鎖的非阻塞版本,它會立即傳回并傳回一個錯誤資訊。 

運用C++, 将緩沖區封裝成class Storage

繼續閱讀