1. 程式人生 > >[linux下]理解Semaphore及其用法詳解

[linux下]理解Semaphore及其用法詳解

Mutex是一把鑰匙,一個人拿了就可進入一個房間,出來的時候把鑰匙交給佇列的第一個。一般的用法是用於序列化對critical section程式碼的訪問,保證這段程式碼不會被並行的執行。



Semaphore是一件可以容納N人的房間,如果人不滿就可以進去,如果人滿了,就要等待有人出來。對於N=1的情況,稱為binary semaphore。一般的用法是,用於限制對於某一資源的同時訪問。



Binary semaphoreMutex的差異:

在 有的系統中Binary semaphore與Mutex是沒有差異的。在有的系統上,主要的差異是mutex一定要由獲得鎖的程序來釋放。而semaphore可以由其它程序釋 放(這時的semaphore實際就是個原子的變數,大家可以加或減),因此semaphore可以用於程序間同步。Semaphore的同步功能是所有 系統都支援的,而Mutex能否由其他程序釋放則未定,因此建議mutex只用於保護critical section。而semaphore則用於保護某變數,或者同步。



關於semaphore和mutex的區別,網上有著名的廁所理論(http://koti.mbnet.fi/niclasw/MutexSemaphore.html):

Mutex:Is a key to a toilet. One person can have the key - occupy the toilet - at the time. When finished, the person gives (frees) the key to the next person in the queue.Officially: “Mutexes are typically used to serialise access to a section of re-entrant code that cannot be executed concurrently by more than one thread. A mutex object only allows one thread into a controlled section, forcing other threads which attempt to gain access to that section to wait until the first thread has exited from that section.”
Ref: Symbian Developer Library(A mutex is really a semaphore with value 1.)

Semaphore:

Is the number of free identical toilet keys. Example, say we have four toilets with identical locks and keys. The semaphore count - the count of keys - is set to 4 at beginning (all four toilets are free), then the count value is decremented as people are coming in. If all toilets are full, ie. there are no free keys left, the semaphore count is 0. Now, when eq. one person leaves the toilet, semaphore is increased to 1 (one free key), and given to the next person in the queue.

Officially: “A semaphore restricts the number of simultaneous users of a shared resource up to a maximum number. Threads can request access to the resource (decrementing the semaphore), and can signal that they have finished using the resource (incrementing the semaphore).”
Ref: Symbian Developer Library

所以,mutex就是一個binary semaphore (值就是0或者1)。但是他們的區別又在哪裡呢?主要有兩個方面:

    * 初始狀態不一樣:mutex的初始值是1(表示鎖available),而semaphore的初始值是0(表示unsignaled的狀態)。隨後的操 作基本一樣。mutex_lock和sem_post都把值從0變成1,mutex_unlock和sem_wait都把值從1變成0(如果值是零就等 待)。初始值決定了:雖然mutex_lock和sem_wait都是執行V操作,但是sem_wait將立刻將當前執行緒block住,直到有其他執行緒 post;mutex_lock在初始狀態下是可以進入的。
    * 用法不一樣(對稱 vs. 非對稱):這裡說的是“用法”。Semaphore實現了signal,但是mutex也有signal(當一個執行緒lock後另外一個執行緒 unlock,lock住的執行緒將收到這個signal繼續執行)。在mutex的使用中,模型是對稱的。unlock的執行緒也要先lock。而 semaphore則是非對稱的模型,對於一個semaphore,只有一方post,另外一方只wait。就拿上面的廁所理論來說,mutex是一個鑰 匙不斷重複的使用,傳遞在各個執行緒之間,而semaphore擇是一方不斷的製造鑰匙,而供另外一方使用(另外一方不用歸還)。

前面的實驗證明,mutex確實能夠做到post和wait的功能,只是大家不用而已,因為它是“mutex”不是semaphore。


下面給出一個例子:

要 讓一個thread在背景不斷的執行,最簡單的方式就是在該thread執行無窮迴圈,如while(1) {},這種寫法雖可行,卻會讓CPU飆高到100%,因為CPU一直死死的等,其實比較好的方法是,背景平時在Sleep狀態,當前景呼叫背景時,背景馬 上被喚醒,執行該做的事,做完馬上Sleep,等待前景呼叫。當背景sem_wait()時,就是馬上處於Sleep狀態,當前景sem_post() 時,會馬上換起背景執行,如此就可避免CPU 100%的情形了。


/*

*//*
    (C) OOMusou 2006 http://oomusou.cnblogs.com

     Filename : pthread_create_semaphore.cpp
     Compiler : gcc 4.10 on Fedora 5 / gcc 3.4 on Cygwin 1.5.21
     Description : Demo how to create thread with semaphore in Linux.
     Release : 12/03/2006
     Compile : g++ -lpthread pthread_create_semaphore.cpp
    *
/
#include <stdio.h> // printf(),
#include <stdlib.h> // exit(), EXIT_SUCCESS
#include <pthread.h> // pthread_create(), pthread_join()
#include <semaphore.h> // sem_init()

sem_t binSem;

void* helloWorld(void* arg);

int main() {
     // Result for System call
    int res = 0;

     // Initialize semaphore
     res =
 sem_init(&binSem, 0, 0);
    if (res) {
         printf("Semaphore initialization failed!!\n");
         exit(EXIT_FAILURE);
     }

     // Create thread
     pthread_t thdHelloWorld;
     res = pthread_create(&thdHelloWorld, NULL, helloWorld, NULL);
    if (res) {
         printf("Thread creation failed!!\n");
         exit(EXIT_FAILURE);
     }

    while(1) {
         // Post semaphore
         sem_post(&binSem);
         printf("In main, sleep several seconds.\n");
        sleep(1);
     }

     // Wait for thread synchronization
     void *threadResult;
     res = pthread_join(thdHelloWorld, &threadResult);
    if (res) {
         printf("Thread join failed!!\n");
         exit(EXIT_FAILURE);
     }

     exit(EXIT_SUCCESS);
}

void* helloWorld(void* arg) {
    while(1) {
         // Wait semaphore
         sem_wait(&binSem);
         printf("Hello World\n");
     }
}


編譯執行:


[[email protected] semaphore]# gcc semaphore.-lpthread
[[email protected] semaphore]# ./a.out
In main, sleep several seconds.
Hello World
In main, sleep several seconds.
Hello World
In main, sleep several seconds.
Hello World
In main, sleep several seconds.
Hello World

相關推薦

linux理解Semaphore及其用法

Mutex是一把鑰匙,一個人拿了就可進入一個房間,出來的時候把鑰匙交給佇列的第一個。一般的用法是用於序列化對critical section程式碼的訪問,保證這段程式碼不會被並行的執行。Semaphore是一件可以容納N人的房間,如果人不滿就可以進去,如果人滿了,就要等待有人出來。對於N=1的情況,稱為bi

理解Semaphore及其用法

Mutex是一把鑰匙,一個人拿了就可進入一個房間,出來的時候把鑰匙交給佇列的第一個。一般的用法是用於序列化對critical section程式碼的訪問,保證這段程式碼不會被並行的執行。Semaphore是一件可以容納N人的房間,如果人不滿就可以進去,如果人滿了,就要等待有人出來。對於N=1的情況,稱為bin

Linux同步工具inotify+rsync使用

server linux 通道 主機 Linux下同步工具inotify+rsync使用詳解 Posted on 2014-12-12 | In Linux | 9 | Visitors 4381. rsync1.1 什麽是rsyncrsync是一個遠程數據同步工具,可通過LAN/WAN

linux cp命令參數及用法---linux 復制文件命令cp

linux file linux cp命令參數及用法詳解---linux 復制文件命令cp [root@Linux ~]# cp [-adfilprsu] 來源檔(source) 目的檔(destination)[root@linux

Linux PS1 PS2 PS3 PS4 提示符

linux提示符很多人在用Linux時,對提示符都不太註重,能夠利用好提示符可更直觀地查看,利於自己的判斷Linux下有PS1 PS2 PS3 PS4 四類提示符,這四個變量都是環境變量,至於系統裏有哪些環境變量,可使用命令 “env”來查看PS1命令提示符PS1有那些配置,或者說PS1裏頭都能配置些命令提示

linuxiptables命令的應用與

iptables 一、iptables的規則表和鏈。 表(tables)提供特定的功能,iptables內置了4個表,即filter表、nat表、mangle表和raw表,分別用於實現包過濾,網絡地址轉換、包重構(修改)和數據跟蹤處理。 鏈(chains)是數據包傳播的路徑,每一條鏈其實就是眾多規則中的

Linuxrar 命令壓縮和解壓

保持 介紹 詳細 註意 壓縮 rar 縮進 command 解壓縮 例1:添加文件或目錄到壓縮檔案中,使用a命令。例如把文件files1添加到abc.rar中,使用a或m命令,a命令把file1文件添加到abc.rar檔案中保持原有的file1文件不變,m命令移動file1

Linux/etc/sysconfig目錄下文件

sysconfig今天給服務器添加防火墻規則時,不小心刪除了一條規則,然後我的遠程連接就斷了,我老大忽然問我iptables配置文件路徑在什麽地方,當時就懵逼了,我還真不知道因為平時全部都是命令添加防火墻,結果被老大給說了基礎不紮實。想想也真是,Linux學習一年多了,當初那麽拼命的學習就是為了打好基礎,本想

linuxrsync文件同步配置

寫入文件 sts ddr ORC 文件的 數據鏡像 根據 數據 watermark 介紹 rsync(remote sync)是unix及類unix平臺下的數據鏡像備份軟件,它不像FTP那樣需要全備份,rsync可以根據數據的變化進行差異備份,從而減少數據流量,提高工作效率

Linuxoracle12c數據庫安裝

shadow follow glibc 格式化磁盤 www ech etc 12c 接收 簡介: oracle12c概述 oracle12c數據庫屬於關系型數據庫,采用C/S模式、支持SQL語言,穩定性、高性能、安全性優於其他官方網站: https://www.oracle

Linux多資料夾編寫Makefile

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Linuxpasswd和shadow檔案內容

一、/etc/passwd /etc/passwd 檔案是一個純文字檔案,每行採用了相同的格式:  name:password:uid:gid:comment:home:shell  name 使用者登入名  password 使用者口令。此域中的口令是加密的,常用x表示。當用戶登入系統時,系統對輸入的口令採

linuxrz和sz用發

在ubuntu系統下輸入如下: 1:第一步 [email protected]:~/node$ sr 程式“sr”尚未安裝。 您可以使用以下命令安裝: sudo apt install surfraw 2:第二步 [email protected]:~/node$

Linux的壓縮zip,tar命令及例項

Linux下的壓縮解壓縮命令詳解及例項 例項:壓縮伺服器上當前目錄的內容為xxx.zip檔案 zip -r xxx.zip ./* 解壓zip檔案到當前目錄 unzip filename.zip ============================ 另:有些伺服器

Xshell拖拽檔案到linux(rz和sz命令用法

在linux中rz 和 sz 命令允許開發板與主機通過串列埠進行傳遞檔案了,下面我們就來簡單的介紹一下rz 和 sz 命令的例子。 rz,sz是Linux/Unix同Windows進行ZModem檔案傳輸的命令列工具。 優點就是不用再開一個sftp工具登入上去上傳下

CentOS LinuxVNC Server遠端桌面配置

一、安裝相應桌面環境與vnc服務端和客戶端: # yum groupinstall "GNOME Desktop Environment"(CentOS 5.x安裝GNOME桌面環境) # yum groupinstall "X Window System" "Desktop"(CentOS 6.

CentOS \Linux 6版本系統命令及其使用

概述 常用的linux命令,分為檔案管理、磁碟管理、使用者管理、軟體管理、系統管理等。 檔案管理 ls命令 使用許可權:所有使用者 使用方式:ls [-a

linux的藍芽驅動程式

1、首先要做Bluez協議棧的移植,這樣在開發板上才可以用hciconfig, hcitool等命令。關於bluez協議棧的移植步驟網上很多。 2、該驅動是USB藍芽裝置驅動,分析根據藍芽驅動的寫的順序進行。因為只是要做資料的傳輸,所以講用於語音的等時傳輸部分去掉了。 首先

fgets函式及其用法

雖然用 gets() 時有空格也可以直接輸入,但是 gets() 有一個非常大的缺陷,即它不檢查預留儲存區是否能夠容納實際輸入的資料,換句話說,如果輸入的字元數目大於陣列的長度,gets 無法檢測到這個問題,就會發生記憶體越界,所以程式設計時建議使用 fgets()。 fgets() 的原型為: 1

linuxmysql配置檔案my.cnf

用來容納InnoDB為資料表的表空間: 可能涉及一個以上的檔案; 每一個表空間檔案的最大長度都必須以位元組(B)、兆位元組(MB)或千兆位元組(GB)為單位給出; 表空間檔案的名字必須以分號隔開; 最後一個表空間檔案還可以帶一個autoextend屬性和一個最大長度(max:n)。例如,ibdata1:1G;