新聞中心
介紹

“真誠服務(wù),讓網(wǎng)絡(luò)創(chuàng)造價值”是我們的服務(wù)理念,創(chuàng)新互聯(lián)團(tuán)隊十余年如一日始終堅持在網(wǎng)站建設(shè)領(lǐng)域,為客戶提供優(yōu)質(zhì)服。不管你處于什么行業(yè),助你輕松跨入“互聯(lián)網(wǎng)+”時代,PC網(wǎng)站+手機(jī)網(wǎng)站+公眾號+微信小程序定制開發(fā)。
Linux操作系統(tǒng)中,信號量是用于進(jìn)程或線程之間通信和互斥控制的一種機(jī)制。信號量可用于協(xié)調(diào)多個進(jìn)程或線程之間的訪問。在多個進(jìn)程或線程之間,通過使用信號量機(jī)制,可以確保只有一個進(jìn)程或線程可以訪問共享資源。
信號量分為兩種:二元信號量和計數(shù)信號量。其中,二元信號量只能取0或1兩個值,適合用于互斥控制;計數(shù)信號量可以取任何非負(fù)整數(shù),適合用于進(jìn)程或線程之間通信。
本文將詳細(xì)介紹Linux中信號量的使用方法以及在實踐中如何使用信號量實現(xiàn)互斥控制。
一、信號量API
在Linux中,信號量的API有三個函數(shù),分別是semget、semop和semctl。
1.1 semget
semget函數(shù)用于創(chuàng)建一個新的信號量或獲取一個已存在的信號量。
基本的函數(shù)格式如下:
“`
#include
#include
#include
int semget(key_t key, int nsems, int sem);
“`
其中,key是信號量標(biāo)識符,在創(chuàng)建或獲取時需要指定一個唯一的標(biāo)識符。nsems指定需要創(chuàng)建或獲取的信號量數(shù)量,sem參數(shù)則是控制信號量的標(biāo)志,通常使用IPC_CREAT標(biāo)志創(chuàng)建一個新的信號量。
1.2 semop
semop函數(shù)用于對信號量進(jìn)行P操作和V操作。
基本的函數(shù)格式如下:
“`
#include
#include
#include
int semop(int semid, struct sembuf *sops, size_t nsops);
“`
其中,semid是信號量的標(biāo)識符,sops是一個指向sembuf結(jié)構(gòu)數(shù)組的指針,每一個sembuf結(jié)構(gòu)體表示要進(jìn)行的操作(P或V)以及操作的信號量編號和操作數(shù)量。
1.3 semctl
semctl函數(shù)用于控制信號量的各種屬性。
基本的函數(shù)格式如下:
“`
#include
#include
#include
int semctl(int semid, int semnum, int cmd, …);
“`
其中,semid是信號量的標(biāo)識符,semnum是信號量的序號,cmd是要執(zhí)行的操作碼,后面的可選參數(shù)依賴于cmd的不同。
二、信號量的實際應(yīng)用
信號量在操作系統(tǒng)中被廣泛應(yīng)用于進(jìn)程或線程之間的通信和互斥控制,下面將詳細(xì)介紹信號量在互斥控制中的應(yīng)用。
2.1 互斥控制
在多進(jìn)程或多線程程序中,為了確保在某個資源被使用時只有一個進(jìn)程或線程能夠訪問該資源,需要使用信號量機(jī)制來實現(xiàn)互斥控制。
例如,假設(shè)在一個多進(jìn)程程序中多個進(jìn)程需要同時訪問一個共享資源,為了避免多個進(jìn)程同時訪問該資源而引發(fā)的沖突,需要使用信號量來進(jìn)行互斥控制。
以下是使用信號量控制互斥訪問共享資源的示例程序:
“`
#include
#include
#include
#include
#include
#define SEM_KEY 39999
int semid;
int init_sem(int sem_key)
{
union semun arg;
int semid = semget(sem_key, 1, IPC_CREAT | IPC_EXCL | 0666);
if(semid == -1){
semid = semget(sem_key, 1, 0666);
if(semid == -1){
perror(“semget”);
exit(1);
}
}
arg.val = 1;
semctl(semid, 0, SETVAL, arg);
return semid;
}
void P(int semid)
{
struct sembuf sem_p;
sem_p.sem_num = 0;
sem_p.sem_op = -1;
sem_p.sem_ = SEM_UNDO;
semop(semid, &sem_p, 1);
}
void V(int semid)
{
struct sembuf sem_v;
sem_v.sem_num = 0;
sem_v.sem_op = 1;
sem_v.sem_ = SEM_UNDO;
semop(semid, &sem_v, 1);
}
int mn()
{
semid = init_sem(SEM_KEY);
pid_t pid;
pid = fork();
if(pid == -1){
perror(“fork”);
exit(1);
}else if(pid == 0){
P(semid);
printf(“Child process get the semaphore.\n”);
sleep(2);
V(semid);
printf(“Child process release the semaphore.\n”);
}else{
printf(“Parent process trying to get the semaphore.\n”);
P(semid);
printf(“Parent process get the semaphore.\n”);
V(semid);
printf(“Parent process release the semaphore.\n”);
}
return 0;
}
“`
在上述代碼中,我們使用了三個函數(shù)P、V和init_sem來實現(xiàn)對共享資源的互斥訪問。
其中,init_sem函數(shù)用于創(chuàng)建或獲取一個信號量,并設(shè)定初始的值為1,即初始時資源未被占用。
P函數(shù)用于對共享資源進(jìn)行加鎖操作,即申請信號量。在申請信號量時,我們將信號量的值減1。如果信號量的值為0,則表示資源正在被占用,進(jìn)程或線程需要等待。
V函數(shù)用于對共享資源進(jìn)行解鎖操作,即釋放信號量。在釋放信號量時,我們將信號量的值加1。如果有進(jìn)程或線程在等待該資源,我們會將其喚醒并繼續(xù)執(zhí)行。
在上述代碼中,我們首先創(chuàng)建了一個信號量,并將其值設(shè)為1。然后創(chuàng)建了一個子進(jìn)程,在子進(jìn)程中調(diào)用P函數(shù)占用信號量,表示子進(jìn)程獲得了對該資源的訪問權(quán)。在P函數(shù)中,如果信號量的值為0,則表示資源正在被占用,進(jìn)程或線程需要等待。在子進(jìn)程等待了2秒鐘后,使用V函數(shù)釋放信號量,表示占用該資源的操作已經(jīng)完成。
在子進(jìn)程完成操作后,父進(jìn)程嘗試獲取信號量,如果獲取到了信號量,則表示父進(jìn)程獲得了對該資源的訪問權(quán)。在父進(jìn)程中,我們同樣使用V函數(shù)釋放占用的信號量。
通過上述互斥控制的示例程序,我們可以了解到,在編寫多進(jìn)程或多線程的程序時,使用信號量機(jī)制可以很好地控制資源的訪問,保證操作的正確性和安全性。
3.
相關(guān)問題拓展閱讀:
- linux mutex互斥體和semaphore信號量的區(qū)別
linux mutex互斥體和semaphore信號量的區(qū)別
mutex保護(hù)的資源在同一時刻只允許一個task進(jìn)行訪問;semaphore根據(jù)初始值n可以允許至旁衡鍵多n個task訪問。
semaphore可以實現(xiàn)攔咐“等待”機(jī)制,一種常見的場景是task0進(jìn)入阻塞狀態(tài)“等待”某個事件發(fā)生,task1觸發(fā)事件后“喚醒”task0。task0在“等待”時處于阻塞運巧狀態(tài)而不是運行狀態(tài),因此不會浪費CPU時間。而一個task在拿到mutex之后釋放之前不宜進(jìn)行太長時間的操作,更不能阻塞。
mutex互斥體只用于保護(hù)臨界區(qū)的代碼(訪問共享資源),而桐襲漏不用于鎖之間的同步,即一個線程釋放mutex鎖后,馬上又可能獲取同一個鎖,禪鎮(zhèn)而不管其它正在等待該mutex鎖的其它線程。
semaphore信號量除了起到保護(hù)臨界區(qū)的作用外,還用于鎖同步的功能,即一個線程釋放semaphore后,會保證正在等待該semaphore的線程優(yōu)先執(zhí)行,而不會馬上在獲取同一個semaphore。
如果兩個局爛線程想通過一個鎖達(dá)到輸出1,2,1,2,1,2這樣的序列,應(yīng)使用semaphore, 而使用mutex的結(jié)果可能為1,1,1,1,1,2,2,2,111…..。
mutex互斥體只用于保護(hù)臨界區(qū)的代碼(訪問共享資源),而桐襲漏不用于鎖之間的同步,即一個線程釋放mutex鎖后,馬上又可能獲取同一個鎖,禪鎮(zhèn)而不管其它正在等待該mutex鎖的其它線程。
semaphore信號量除了起到保護(hù)臨界區(qū)的作用外,還用于鎖同步的功能,即一個線程釋放semaphore后,會保證正在等待該semaphore的線程優(yōu)先執(zhí)行,而不會馬上在獲取同一個semaphore。
如果兩個局爛線程想通過一個鎖達(dá)到輸出1,2,1,2,1,2這樣的序列,應(yīng)使用semaphore, 而使用mutex的結(jié)果可能為1,1,1,1,1,2,2,2,111…..。
關(guān)于linux 信號量互斥控制的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
網(wǎng)站標(biāo)題:Linux中信號量互斥控制詳解(linux信號量互斥控制)
文章地址:http://www.dlmjj.cn/article/cdoecdh.html


咨詢
建站咨詢
