新聞中心
在Linux系統(tǒng)中,信號量機制是一個非常重要的IPC(進程間通信)方式之一。通過使用信號量,可以讓多個進程之間互相配合,實現(xiàn)共享資源的訪問和互斥訪問。本文將從信號量的概念、在Linux系統(tǒng)中信號量的實現(xiàn)方式以及使用信號量實現(xiàn)進程同步和互斥的應用方面進行探究。

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供濠江網(wǎng)站建設、濠江做網(wǎng)站、濠江網(wǎng)站設計、濠江網(wǎng)站制作等企業(yè)網(wǎng)站建設、網(wǎng)頁設計與制作、濠江企業(yè)網(wǎng)站模板建站服務,十余年濠江做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡服務。
一、信號量的概念
信號量(Semaphore)是一種用于多進程之間同步互斥的機制,是操作系統(tǒng)中的一個標準機制,可以用于實現(xiàn)資源的互斥訪問和進程之間的同步。在Linux系統(tǒng)中,信號量是一個32位的整數(shù),對其進行原子操作,比如加、減等,用來實現(xiàn)進程的同步、互斥操作。
信號量的定義如下:
typedef union semun{
int val; // 信號量的值
struct semid_ds *buf; // IPC信號量的管理結構體
unsigned short *array; // 數(shù)組指針
struct seminfo *__buf; // 具體信息
}semun;
其中,對于不同的應用場景,struct semid_ds和struct seminfo所定義的屬性也有所不同。在Linux系統(tǒng)中,信號量常常分為System V IPC和POSIX IPC兩種類型。
二、在Linux中的信號量實現(xiàn)方式
在Linux中,信號量的實現(xiàn)方式多種多樣,如System V IPC、POSIX IPC、SysVIPC、POSIX named semaphores等,下面主要對System V IPC進行介紹。
System V IPC是一種IPC機制,包括消息隊列、信號量和共享內(nèi)存等。它的實現(xiàn)方式基于內(nèi)核態(tài),無法在用戶態(tài)直接操作,需要通過系統(tǒng)調(diào)用的方式來操作。
Linux系統(tǒng)中實現(xiàn)信號量機制的主要函數(shù)有semget()、semop()和semctl()。
1、 semget()函數(shù):創(chuàng)建和獲取一個信號量
通過調(diào)用semget()函數(shù)來創(chuàng)建和獲取一個信號量,semget()函數(shù)的定義如下:
#include
#include
#include
int semget(key_t key, int nsems, int sem);
其中,key是信號量的標識符,nsems表示需要的信號量個數(shù),sem則指定信號量的訪問權限等設置。
2、semop()函數(shù):進行信號量的加減操作
通過調(diào)用semop()函數(shù)來進行信號量的加減操作,semop()函數(shù)的定義如下:
#include
#include
#include
int semop(int semid, struct sembuf *sops, size_t nsops);
其中,semid是信號量的標識符,sops是一個結構體,用于指定需要進行的操作,nsops表示進行操作的個數(shù)。
3、semctl()函數(shù):進行信號量控制操作
通過調(diào)用semctl()函數(shù)來進行信號量的控制操作,semctl()函數(shù)的定義如下:
#include
#include
#include
int semctl(int semid, int semnum, int cmd, …);
其中,semid是信號量的標識符,semnum表示需要控制的信號量在中的下標,cmd表示需要進行的控制操作。
三、信號量的使用
通過信號量的加減操作以及控制操作,可以實現(xiàn)多個進程之間的同步和互斥。比如通過以下方式可以實現(xiàn)多個進程之間的同步:
1、設定一個計數(shù)器counter,初值為0
2、定義一個信號量semid,初值為0
3、一個進程P執(zhí)行semop(semid, 1),如果semid的值為0,則等待;否則counter+1
4、一個進程V執(zhí)行semop(semid, -1),如果counter為0,則等待;否則counter-1
使用信號量實現(xiàn)進程同步和互斥的應用場景至少有以下幾個:
1、文件讀寫鎖
多個進程同時對一個文件進行讀寫操作時,可能會出現(xiàn)訪問競爭的情況,為此可以使用信號量來進行控制,實現(xiàn)文件的讀寫鎖。
2、生產(chǎn)者和消費者
在生產(chǎn)者和消費者的場景中,生產(chǎn)者可以生產(chǎn)一定數(shù)量的物品供消費者使用,而消費者則需要在生產(chǎn)數(shù)量有限的情況下,對資源進行協(xié)調(diào)訪問,避免競爭的發(fā)生,從而保證生產(chǎn)者和消費者之間的協(xié)作高效完成。
3、互斥調(diào)用
在互斥調(diào)用場景中,需要協(xié)調(diào)多個進程共同訪問共享資源,通過使用信號量,可以避免多個進程同時調(diào)用共享資源,導致沖突和死鎖的情況出現(xiàn)。
成都網(wǎng)站建設公司-創(chuàng)新互聯(lián)為您提供網(wǎng)站建設、網(wǎng)站制作、網(wǎng)頁設計及定制高端網(wǎng)站建設服務!
linux進程間通信問題 我想用共享內(nèi)存的方式實現(xiàn)信號量控制一個不許并行的的函數(shù) 請問下面我的代碼合理嗎
我想你的目的是有一段代碼 (即你標的 /*……….只能單獨進行的函數(shù)………*/)
在任意時刻最多只能有最多一個進程執(zhí)行,是吧。
首先,你的臘胡做法是錯的…… 簡單的說,原因是由于
while( *shmaddr );
*shmaddr = 1;
這兩行代碼不是一個原子操作,從while判斷出 *shmaddr等于0 到 *shmaddr=1 之間,另外一個或多個進程可能也會得到 *shmaddr==0 的判斷,從而導致多個進程同時進入 /*……….只能單獨進行的函數(shù)………*/
具體關于互斥的基本原理,以及你為什么錯,可以找一本講操作系統(tǒng)原理 (關于進程同步戚局游的高銷內(nèi)容)去看。
所以,用 shared memory 來實現(xiàn)進程同步肯定是不行的,正確的做法是使用 semaphore, 具體可以參考 《unix 環(huán)境高級編程》中關于 semaphore (信號量)使用的章節(jié)。
看你好像完全搞混了。什么叫用共享內(nèi)存的方式實現(xiàn)信號量控制不能并行的代碼?
首先共享內(nèi)存和信號量都可以實現(xiàn)進程間通信,但是他們的作用或者說使用的方向是有明顯的區(qū)別的:
1:共享內(nèi)存是創(chuàng)建一塊內(nèi)存區(qū)域,多個進程可以同時訪問該區(qū)域,一般用于進程間數(shù)據(jù)傳輸,效率比較明顯基運兄。
2:信號量則完全不同,信號量主要是用來控制臨界資源的訪悄嫌問,也就是你說的不能并行的函數(shù)/代碼。
3:說一下實現(xiàn),共享內(nèi)存直接用API就可以了,信號量一般會進行封裝,類似于對鏈表的操作進行一些簡單的函數(shù)封裝一樣,下面給出信號量的使用實例代碼,可以參考:
sem_ctl.c文件內(nèi)容:
int init_sem(int sem_id,int init_value)
{
union semun sem_union;
sem_union.val = init_value;
if(semctl(sem_id,0,SETVAL,sem_union) == -1)
{
perror(“semctl”);
return -1;
}
return 0;
}
int del_sem(int sem_id)
{
union semun sem_union;
if(semctl(sem_id,0,IPC_RMID,sem_union) == -1)
{
perror(“delete semaphore”);
return -1;
}
return 0;
}
int sem_p(int sem_id)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1;
sem_b.sem_ = SEM_UNDO;
if(semop(sem_id,&sem_b,1) ==-1)
{
perror(“P operation”);
return -1;
}
return 0;
}
int sem_v(int sem_id)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1;
sem_b.sem_ = SEM_UNDO;
if(semop(sem_id,&sem_b,1) == -1)
{
perror(“V opration”);
return -1;
}
return 0;
}
sem_ctl.h文件內(nèi)容搏襲:
#include
#include
#include
#include
#include
#include
#include
#define MAX 128
int count; //全局變量,即臨界資源
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int init_sem(int sem_id,int init_value);
int del_sem(int sem_id);
int sem_p(int sem_id);
int sem_v(int sem_id);
在應用程序中只要包含sem_ctl.h就可以使用信號量的p、v操作了,下面給出2個c程序同時操作該信號量的情況,類似于:
server.c文件內(nèi)容如下:
#include “util.h”
#include
int semid;
void sighandler(int signo)
{
del_sem(semid);
exit(0);
}
void server()
{
key_t key;
initcount();
if((key = ftok(“.”,’e’)) == -1)
{
perror(“ftok”);
exit(1);
}
if((semid = semget(key,1,0666|IPC_CREAT|IPC_EXCL)) == -1)
{
perror(“semget”);
exit(1);
}
printf(“the semid is :%d\n”,semid);
init_sem(semid, 0);
signal(SIGINT,sighandler);
signal(SIGUSR1,sighandler);
signal(SIGALRM,sighandler);
while(1)
{
sem_p(semid);
/* do something */
printf(“count =%d\n”,count++);
sem_v(semid);
sleep(2);
}
}
int main(void)
{
server();
}
client.c文件內(nèi)容如下:
#include “sem_ctl.h”
void custom()
{
int semid;
key_t key;
if((key = ftok(“.”,’e’)) == -1)
{
perror(“ftok”);
exit(1);
}
if((semid = semget(key,0,0)) == -1)
{
perror(“semget”);
exit(1);
}
printf(“the semid is :%d\n”,semid);
while(1)
{
sem_p(semid); //獲得信號量,同一時間只有一個進程能獲得該信號量
/* do something */
printf(“count =%d\n”,count++);
sem_v(semid); //釋放信號量
sleep(2);
}
}
int main(void)
{
custom();
}
編譯好,運行的時候先運行server再運行client。
關于linux c 信號量的介紹到此就結束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關注本站。
創(chuàng)新互聯(lián)-老牌IDC、云計算及IT信息化服務領域的服務供應商,業(yè)務涵蓋IDC(互聯(lián)網(wǎng)數(shù)據(jù)中心)服務、云計算服務、IT信息化、AI算力租賃平臺(智算云),軟件開發(fā),網(wǎng)站建設,咨詢熱線:028-86922220
網(wǎng)站名稱:探究LinuxC中的信號量機制(linuxc信號量)
文章鏈接:http://www.dlmjj.cn/article/cdgjcph.html


咨詢
建站咨詢
