當前位置:首頁 » 操作系統 » semaphorelinux

semaphorelinux

發布時間: 2022-03-02 05:08:20

A. linux 信號量操作函數

semget()
可以使用系統調用semget()創建一個新的信號量集,或者存取一個已經存在的信號量集:
系統調用:semget();
原型:intsemget(key_t key,int nsems,int semflg);
返回值:如果成功,則返回信號量集的IPC標識符。如果失敗,則返回-1:errno=EACCESS(沒有許可權)
EEXIST(信號量集已經存在,無法創建)
EIDRM(信號量集已經刪除)
ENOENT(信號量集不存在,同時沒有使用IPC_CREAT)
ENOMEM(沒有足夠的內存創建新的信號量集)
ENOSPC(超出限制)
系統調用semget()的第一個參數是關鍵字值(一般是由系統調用ftok()返回的)。系統內核將此值和系統中存在的其他的信號量集的關鍵字值進行比 較。打開和存取操作與參數semflg中的內容相關。IPC_CREAT如果信號量集在系統內核中不存在,則創建信號量集。IPC_EXCL當和 IPC_CREAT一同使用時,如果信號量集已經存在,則調用失敗。如果單獨使用IPC_CREAT,則semget()要麼返回新創建的信號量集的標識 符,要麼返回系統中已經存在的同樣的關鍵字值的信號量的標識符。如果IPC_EXCL和IPC_CREAT一同使用,則要麼返回新創建的信號量集的標識 符,要麼返回-1。IPC_EXCL單獨使用沒有意義。參數nsems指出了一個新的信號量集中應該創建的信號量的個數。信號量集中最多的信號量的個數是 在linux/sem.h中定義的:
#defineSEMMSL32/*<=512maxnumofsemaphoresperid*/
下面是一個打開和創建信號量集的程序:
intopen_semaphore_set(key_t keyval,int numsems)
{
intsid;
if(!numsems)
return(-1);
if((sid=semget(mykey,numsems,IPC_CREAT|0660))==-1)
{
return(-1);
}
return(sid);
}
};
==============================================================
semop()
系統調用:semop();
調用原型:int semop(int semid,struct sembuf*sops,unsign ednsops);
返回值:0,如果成功。-1,如果失敗:errno=E2BIG(nsops大於最大的ops數目)
EACCESS(許可權不夠)
EAGAIN(使用了IPC_NOWAIT,但操作不能繼續進行)
EFAULT(sops指向的地址無效)
EIDRM(信號量集已經刪除)
EINTR(當睡眠時接收到其他信號)
EINVAL(信號量集不存在,或者semid無效)
ENOMEM(使用了SEM_UNDO,但無足夠的內存創建所需的數據結構)
ERANGE(信號量值超出范圍)
第一個參數是關鍵字值。第二個參數是指向將要操作的數組的指針。第三個參數是數組中的操作的個數。參數sops指向由sembuf組成的數組。此數組是在linux/sem.h中定義的:
/*semop systemcall takes an array of these*/
structsembuf{
ushortsem_num;/*semaphore index in array*/
shortsem_op;/*semaphore operation*/
shortsem_flg;/*operation flags*/
sem_num將要處理的信號量的個數。
sem_op要執行的操作。
sem_flg操作標志。
如果sem_op是負數,那麼信號量將減去它的值。這和信號量控制的資源有關。如果沒有使用IPC_NOWAIT,那麼調用進程將進入睡眠狀態,直到信號 量控制的資源可以使用為止。如果sem_op是正數,則信號量加上它的值。這也就是進程釋放信號量控制的資源。最後,如果sem_op是0,那麼調用進程 將調用sleep(),直到信號量的值為0。這在一個進程等待完全空閑的資源時使用。

B. 為什麼要設置linux semaphore參數

通過ipcs -s 可以看到SEMAPHORE,在這里可以看到NSEMS是254(環境基於RHEL 6(32BIT),ORACLE DATABASE 11.2.0.1.0)
[root@hy1 oracle]# ipcs -s
------ Semaphore Arrays --------
key semid owner perms nsems
0x39c3211c 1671170 oracle 660 254
這個254表示什麼呢?是ORACLE進程數嗎?
[root@hy1 oracle]# ps -eaf | grep oracle | wc -l
50
可能看到整個ORACLE用戶的進程只有 50
經常官方文檔建議這個參數設置為PROCESSES再加150,那麼這個參數和PROCESSES應該有關,

SQL> show parameter processes;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
processes integer 250

在這里PROCESSES為250,其他的4代表什麼呢?
使用oradebug ipc可以跟蹤當前的IPC情況

Maximum processes: = 250
Number of semaphores per set: = 254
Semaphores key overhead per set: = 4
User Semaphores per set: = 250
Number of semaphore sets: = 1
Semaphore identifiers: = 1
Semaphore List=
1671170
可以看到4為SEAMPHORE本身的開銷,再加上PROCESSES定義的大小,剛好是254
kernel.semmsl 定義了一個信號集的信號數,這個參數設置建議為PROCESSES+150,當然系統的默認設置128也不會有問題
但是需要請求多個信號集,從某種程度上來說降低了效率
kernel.semopm定義了每次信號函數能操作的最大信號數,建議和semmsl相等,這樣一次調用就能完成所有的集號操作,而不
需要多次調用
kernel.semmni定了系統中的信號集的個數,一般125足夠用了
kernel.semmns定義了系統中最大信號數,建議值為 kernel.semmsl * kernel.semmni.

需要注意的是不要弄混信號和信號集的概念。

C. linux編程時的信號量問題。 我以前用過的信號量頭文件是<semaphore.h>,而現在又發現還有個<sys/sem.h>

semaphore.h 提供的是 POSIX 標準定義的 semaphore 介面 ( sem_open, sem_wait, ...) ,這組介面使用更簡單,設計的較好。

而 sys/sem.h 里 提供的是符合 System V 標準的 semaphore介面 (semget, semop, ...),這些介面都比較老了, linux提供主要是為了兼容老代碼。

對於 linux 開發來說,新寫的代碼,都應該考慮採用 POSIX 標準的信號量。

D. Linux 中編程的 semaphore結構體在哪個頭文件中

semaphore.h定義的是內核里用semaphore,用戶態程序用的sem_t也在名叫semaphore.h的文件里定義,不過應該在系統的include目錄下,而不是在內核源代碼了

E. linux mutex互斥體和semaphore信號量的區別

  1. mutex保護的資源在同一時刻只允許一個task進行訪問;semaphore根據初始值n可以允許至多n個task訪問。

  2. semaphore可以實現「等待」機制,一種常見的場景是task0進入阻塞狀態「等待」某個事件發生,task1觸發事件後「喚醒」task0。task0在「等待」時處於阻塞狀態而不是運行狀態,因此不會浪費CPU時間。而一個task在拿到mutex之後釋放之前不宜進行太長時間的操作,更不能阻塞。

F. Linux信號 機制和Linux信號量機制的區別

首先,一句話總結它們之間的區別:

字面上相似,但是本質上存在巨大的差別!請看詳細解答...
Linux信號(signal) 機制

signal,又簡稱為信號(軟中斷信號)用來通知進程發生了非同步事件。

原理:

一個進程收到一個信號與處理器收到一個中斷請求可以說是一樣的。信號是進程間通信機制中唯一的非同步通信機制,一個進程不必通過任何操作來等待信號的到達,事實上,進程也不知道信號到底什麼時候到達。進程之間可以互相通過系統調用kill發送軟中斷信號。內核也可以因為內部事件而給進程發送信號,通知進程發生了某個事件。信號機制除了基本通知功能外,還可以傳遞附加信息。

分類:
從兩個不同的分類角度對信號進行:
可靠性方面:可靠信號與不可靠信號;
與時間的關繫上:實時信號與非實時信號。

部分定義轉自:http://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html

Linux信號量(semaphore)機制
Linux內核的信號量用來操作系統進程間同步訪問共享資源。

原理:信號量在創建時需要設置一個初始值,表示同時可以有幾個任務可以訪問該信號量保護的共享資源,初始值為1就變成互斥鎖(Mutex),即同時只能有一個任務可以訪問信號量保護的共享資源。
一個任務要想訪問共享資源,首先必須得到信號量,獲取信號量的操作將把信號量的值減1,若當前信號量的值為負數,表明無法獲得信號量,該任務必須掛起在該信號量的等待隊列等待該信號量可用;若當前信號量的值為非負數,表示可以獲得信號量,因而可以立刻訪問被該信號量保護的共享資源。
當任務訪問完被信號量保護的共享資源後,必須釋放信號量,釋放信號量通過把信號量的值加1實現,如果信號量的值為非正數,表明有任務等待當前信號量,因此它也喚醒所有等待該信號量的任務。

常用的信號量的API:

DECLARE_MUTEX(name)

該宏聲明一個信號量name並初始化它的值為0,即聲明一個互斥鎖。
DECLARE_MUTEX_LOCKED(name)

該宏聲明一個互斥鎖name,但把它的初始值設置為0,即鎖在創建時就處在已鎖狀態。因此對於這種鎖,一般是先釋放後獲得。
void sema_init (struct semaphore *sem, int val);

該函用於數初始化設置信號量的初值,它設置信號量sem的值為val。
void init_MUTEX (struct semaphore *sem);

該函數用於初始化一個互斥鎖,即它把信號量sem的值設置為1。
void init_MUTEX_LOCKED (struct semaphore *sem);

該函數也用於初始化一個互斥鎖,但它把信號量sem的值設置為0,即一開始就處在已鎖狀態。
void down(struct semaphore * sem);

該函數用於獲得信號量sem,它會導致睡眠,因此不能在中斷上下文(包括IRQ上下文和softirq上下文)使用該函數。該函數將把sem的值減1,如果信號量sem的值非負,就直接返回,否則調用者將被掛起,直到別的任務釋放該信號量才能繼續運行。
int down_interruptible(struct semaphore * sem);

該函數功能與down類似,不同之處為,down不會被信號(signal)打斷,但down_interruptible能被信號打斷,因此該函數有返回值來區分是正常返回還是被信號中斷,如果返回0,表示獲得信號量正常返回,如果被信號打斷,返回-EINTR。
int down_trylock(struct semaphore * sem);

該函數試著獲得信號量sem,如果能夠立刻獲得,它就獲得該信號量並返回0,否則,表示不能獲得信號量sem,返回值為非0值。因此,它不會導致調用者睡眠,可以在中斷上下文使用。
void up(struct semaphore * sem);

該函數釋放信號量sem,即把sem的值加1,如果sem的值為非正數,表明有任務等待該信號量,因此喚醒這些等待者。

實例:
信號量在絕大部分情況下作為互斥鎖使用,下面以console驅動系統為例說明信號量的使用。

在內核源碼樹的kernel/printk.c中,使用宏DECLARE_MUTEX聲明了一個互斥鎖console_sem,它用於保護console驅動列表console_drivers以及同步對整個console驅動系統的訪問。

G. linux中mutex和semaphore的區別

mutex互斥體只用於保護臨界區的代碼(訪問共享資源),而不用於鎖之間的同步,即一個線程釋放mutex鎖後,馬上又可能獲取同一個鎖,而不管其它正在等待該mutex鎖的其它線程。
semaphore信號量除了起到保護臨界區的作用外,還用於鎖同步的功能,即一個線程釋放semaphore後,會保證正在等待該semaphore的線程優先執行,而不會馬上在獲取同一個semaphore。
如果兩個線程想通過一個鎖達到輸出1,2,1,2,1,2這樣的序列,應使用semaphore, 而使用mutex的結果可能為1,1,1,1,1,2,2,2,111.....。

H. spinlock 和 Semaphore信號量的區別

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

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

Binary semaphore與Mutex的差異:

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

另一個概念是spin lock,這是一個內核態概念。spin lock與semaphore的主要區別是spin lock是busy waiting,而semaphore是sleep。對於可以sleep的進程來說,busy waiting當然沒有意義。對於單CPU的系統,busy waiting當然更沒意義(沒有CPU可以釋放鎖)。因此,只有多CPU的內核態非進程空間,才會用到spin lock。Linux kernel的spin lock在非SMP的情況下,只是關irq,沒有別的操作,用於確保該段程序的運行不會被打斷。其實也就是類似mutex的作用,串列化對critical section的訪問。但是mutex不能保護中斷的打斷,也不能在中斷處理程序中被調用。而spin lock也一般沒有必要用於可以sleep的進程空間。
---------------------------------------------------------------------------------------------

內核同步措施
為了避免並發,防止競爭。內核提供了一組同步方法來提供對共享數據的保護。 我們的重點不是介紹這些方法的詳細用法,而是強調為什麼使用這些方法和它們之間的差別。
Linux 使用的同步機制可以說從2.0到2.6以來不斷發展完善。從最初的原子操作,到後來的信號量,從大內核鎖到今天的自旋鎖。這些同步機制的發展伴隨 Linux從單處理器到對稱多處理器的過度;伴隨著從非搶占內核到搶占內核的過度。鎖機制越來越有效,也越來越復雜。
目前來說內核中原子操作多用來做計數使用,其它情況最常用的是兩種鎖以及它們的變種:一個是自旋鎖,另一個是信號量。我們下面就來著重介紹一下這兩種鎖機制。

自旋鎖

自旋鎖是專為防止多處理器並發而引入的一種鎖,它在內核中大量應用於中斷處理等部分(對於單處理器來說,防止中斷處理中的並發可簡單採用關閉中斷的方式,不需要自旋鎖)。
自旋鎖最多隻能被一個內核任務持有,如果一個內核任務試圖請求一個已被爭用(已經被持有)的自旋鎖,那麼這個任務就會一直進行忙循環——旋轉——等待鎖重新可用。要是鎖未被爭用,請求它的內核任務便能立刻得到它並且繼續進行。自旋鎖可以在任何時刻防止多於一個的內核任務同時進入臨界區,因此這種鎖可有效地避免多處理器上並發運行的內核任務競爭共享資源。
事實上,自旋鎖的初衷就是:在短期間內進行輕量級的鎖定。一個被爭用的自旋鎖使得請求它的線程在等待鎖重新可用的期間進行自旋(特別浪費處理器時間),所以自旋鎖不應該被持有時間過長。如果需要長時間鎖定的話, 最好使用信號量。
自旋鎖的基本形式如下:
spin_lock(&mr_lock);
//臨界區
spin_unlock(&mr_lock);
因為自旋鎖在同一時刻只能被最多一個內核任務持有,所以一個時刻只有一個線程允許存在於臨界區中。這點很好地滿足了對稱多處理機器需要的鎖定服務。在單處理器上,自旋鎖僅僅當作一個設置內核搶占的開關。如果內核搶占也不存在,那麼自旋鎖會在編譯時被完全剔除出內核。
簡單的說,自旋鎖在內核中主要用來防止多處理器中並發訪問臨界區,防止內核搶占造成的競爭。另外自旋鎖不允許任務睡眠(持有自旋鎖的任務睡眠會造成自死鎖——因為睡眠有可能造成持有鎖的內核任務被重新調度,而再次申請自己已持有的鎖),它能夠在中斷上下文中使用。
死鎖:假設有一個或多個內核任務和一個或多個資源,每個內核都在等待其中的一個資源,但所有的資源都已經被佔用了。這便會發生所有內核任務都在相互等待,但它們永遠不會釋放已經佔有的資源,於是任何內核任務都無法獲得所需要的資源,無法繼續運行,這便意味著死鎖發生了。自死瑣是說自己佔有了某個資源,然後自己又申請自己已佔有的資源,顯然不可能再獲得該資源,因此就自縛手腳了。

信號量
Linux中的信號量是一種睡眠鎖。如果有一個任務試圖獲得一個已被持有的信號量時,信號量會將其推入等待隊列,然後讓其睡眠。這時處理器獲得自由去執行其它代碼。當持有信號量的進程將信號量釋放後,在等待隊列中的一個任務將被喚醒,從而便可以獲得這個信號量。
信號量的睡眠特性,使得信號量適用於鎖會被長時間持有的情況;只能在進程上下文中使用,因為中斷上下文中是不能被調度的;另外當代碼持有信號量時,不可以再持有自旋鎖。
信號量基本使用形式為:
static DECLARE_MUTEX(mr_sem);//聲明互斥信號量
if(down_interruptible(&mr_sem))
//可被中斷的睡眠,當信號來到,睡眠的任務被喚醒
//臨界區
up(&mr_sem);

信號量和自旋鎖區別
雖然聽起來兩者之間的使用條件復雜,其實在實際使用中信號量和自旋鎖並不易混淆。注意以下原則:
如果代碼需要睡眠——這往往是發生在和用戶空間同步時——使用信號量是唯一的選擇。由於不受睡眠的限制,使用信號量通常來說更加簡單一些。如果需要在自旋鎖和信號量中作選擇,應該取決於鎖被持有的時間長短。理想情況是所有的鎖都應該盡可能短的被持有,但是如果鎖的持有時間較長的話,使用信號量是更好的選擇。另外,信號量不同於自旋鎖,它不會關閉內核搶占,所以持有信號量的代碼可以被搶占。這意味者信號量不會對影響調度反應時間帶來負面影響。

自旋鎖對信號量

需求 建議的加鎖方法
低開銷加鎖 優先使用自旋鎖
短期鎖定 優先使用自旋鎖
長期加鎖 優先使用信號量
中斷上下文中加鎖 使用自旋鎖
持有鎖是需要睡眠、調度 使用信號量

I. 急!LINUX下,GCC編譯,原程序包含<semaphore.h>頭文件,為什麼編譯時說sem_wait,sem_post等未定義的引用

編譯時加上參數:-lpthread

要看報錯的階段,是在編譯還是鏈接階段.
如果編譯時函數沒有找到,那是頭文件的問題,如果鏈接時未定義引用,那是c庫的問題.
如果你的頭文件都正常包含了,那可能你的c庫沒有使能semaphore的支持.

J. linux 信號量是什麼怎麼用

Linux信號量(semaphore)是一種互斥機制。即對某個互斥資源的訪問會收到信號量的保護,在訪問之前需要獲得信號量。
在操作完共享資源後,需釋放信號量,以便另外的進程來獲得資源。獲得和釋放應該成對出現。
獲得信號量集,需要注意的是,獲得的是一個集合,而不是一個單一的信號量。
#include
#include
#include
1: int semget(key_t key,int nsems,int semflg);
key:系統根據這個值來獲取信號量集。
nsems:此信號集包括幾個信號量。
semflg:創建此信號量的屬性。 (IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)
成功則返回該信號量集的ID。
註:
既指定IPC_CREAT又指定IPC_EXCL時,如果系統中該信號量集已經存在,則馬上返回。
如果需要獲得存在的信號量,則將此參數置0.
2: int semctl(int semid,int senum,int cmd....)
semid:信號量ID。
senum:對信號量集中的第幾個信號量進行控制。(從0開始)
cmd:需要進行的操作。(SETVAL是其中的一個)。
根據cmd的不同可能存在第四個參數,cmd=SETVAL時,表示同時信號量可以被獲得幾次,如第四個參數
num=1表示只能被獲得一次,既被信號量保護的資源只能同時被一個程序使用。
該系統調用,是在對信號量初始化時用的。
-3: 「3」前面加了"-"表示當需要使用互斥資源時應該做這步。
int semop(int semid,struct sembuf *sem,int num_elements);
struct sembuf {
unsigned short sem_num; //該信號量集中的第幾個信號量。
int sem_op;//需要獲得還是釋放信號量
int sem_flg;//相關動作
};
num_elements:需要對該信號量集中的多少個信號量進行處理。
獲得信號量時,將sembuf結構提初始化為:
sem_num = 0; //該信號量集中的首個信號量
sem_op = -1; //獲得信號量
sem_flag = IPC_NOWAIT; //如果不能獲得信號量,馬上返回。
semop(semid,_sem,1);
同理釋放信號量時,將sem_op設為1.
以上是對信號量的簡單處理

熱點內容
android計算緩存大小 發布:2024-12-22 19:16:54 瀏覽:659
php訪問模塊 發布:2024-12-22 19:05:24 瀏覽:271
電梯IC加密 發布:2024-12-22 19:04:47 瀏覽:375
腳本圈是引流加粉嗎 發布:2024-12-22 18:41:26 瀏覽:391
ajax文件上傳表單提交 發布:2024-12-22 17:55:00 瀏覽:856
win7無法共享的文件夾 發布:2024-12-22 17:53:39 瀏覽:41
華為手機密碼怎麼解鎖 發布:2024-12-22 17:53:38 瀏覽:554
android設置圓角textview 發布:2024-12-22 17:53:37 瀏覽:739
易語言源碼隱藏 發布:2024-12-22 17:39:23 瀏覽:101
android彈出窗口 發布:2024-12-22 17:16:22 瀏覽:299