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

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


咨詢
建站咨詢
