色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux下進程通訊之信號量集

嵌入式技術 ? 來源:嵌入式技術 ? 作者:嵌入式技術 ? 2022-08-19 19:55 ? 次閱讀

Linux下進程通訊之信號量集

1.簡介

?信號量集,就是由多個信號量組成的一個數組。 作為一個整體, 信號量集中所有的信號量使用同一個等待隊列。 Linux 的信號量集為進程請求多個資源創造了條件。 Linux 規定, 當進程的一個操作需要多個共享資源時, 如果只成功獲得了其中部分資源, 那么這個請求即告失敗, 進程必須立即釋放所有已獲得資源, 已防止形成死鎖。

信號量本質是一個計數器(不設置全局變量是因為進程間是相互獨立的), 用于多進程對共享數據對象的讀取, 它和管道有所不同, 它不以傳送數據為主要目 錄, 主要是用來保護共享資源(信號量也屬于臨界資源), 使得資源在同一時刻只能由一個進程獨享。

2.工作原理

信號量只能進行等待和發送信號兩種操作, 即 P(申請)和 V(釋放)。
(1) P(申請):如果 SV 的值大于 0, 就給他減 1, 如果它的值為 0, 就掛起進程。
(2) V(釋放):如果有其他進程等待信號量而被掛起, 就讓他恢復運行, 如果沒有進程因等待信號量而掛起, 就給他加 1。
在信號量進程 PV 操作時都是為了原子操作(原子操作:單指令的操作, 單條指令的執行時不會被打斷的)。

3. 二值信號量

?? 二元信號量(Binary Semaphore)是最簡單的一種鎖(互斥鎖), 它只有兩種狀態:占用與非占用。 所以它的引 用計數為 1。

4. 查看系統信號量命令

??1.查看信號量組:ipcs -s

[wbyq@wbyq 0414work]$ ipcs -s

--------- 信號量數組 -----------
鍵        semid      擁有者  權限     nsems     
0xd2350092 3          wbyq       666        1  

??2.查看信號量限制信息ipcs -ls

[wbyq@wbyq 0414work]$ ipcs -ls

--------- 信號量限制 -----------
最大數組數量 = 32000
每個數組的最大信號量數目 = 32000
系統最大信號量數 = 1024000000
每次信號量調用最大操作數 = 500
信號量最大值=32767

??3.查看信號量詳細信息:ipcs -s -i

[wbyq@wbyq 0414work]$ ipcs -s -i 3
信號量數組 semid=3
uid=1000	 gid=1000	 cuid=1000	 cgid=1000
模式=0666,訪問權限=0666
nsems = 1
otime = Fri Apr 29 10:27:21 2022  
ctime = Fri Apr 29 10:25:28 2022  
semnum     值        ncount     zcount     pid       
0          1          0          0          13747   

??4.創建信號量:ipcmk -S <信號量個數>

//創建信號量,信號量個數為5個
[wbyq@wbyq 0414work]$ ipcmk -S 5  
信號量 id:6
//查看創建的信號量
[wbyq@wbyq 0414work]$ ipcs -s -i 6

信號量數組 semid=6
uid=1000	 gid=1000	 cuid=1000	 cgid=1000
模式=0644,訪問權限=0644
nsems = 5
otime = 未設置                 
ctime = Fri Apr 29 14:17:16 2022  
semnum     值        ncount     zcount     pid       
0          0          0          0          0         
1          0          0          0          0         
2          0          0          0          0         
3          0          0          0          0         
4          0          0          0          0  

??5.刪除信號量:ipcrm -s

//刪除信號量6
[wbyq@wbyq 0414work]$ ipcs -s 6

--------- 信號量數組 -----------
鍵        semid      擁有者  權限     nsems     
0xd2350092 3          wbyq       666        1         
0xa8132e52 4          wbyq       644        1         
0x9416e553 6          wbyq       644        5         

[wbyq@wbyq 0414work]$ ipcrm -s 6
//刪除后結果
[wbyq@wbyq 0414work]$ ipcs -s

--------- 信號量數組 -----------
鍵        semid      擁有者  權限     nsems     
0xd2350092 3          wbyq       666        1         
0xa8132e52 4          wbyq       644        1   

5.信號量相關函數

#include 
#include 
#include 
int semget(key_t key, int nsems, int semflg);
函數功能:創建信號量
形參:key ?鍵值,ftok產生
???nsems?信號量個數,幾乎總是為1
? ? ?semflg?標志 IPC_CREAT|0666
返回值:失敗返回-1,成功返回semid
int semctl(int semid, int semnum, int cmd, …);
函數功能:信號量控制函數
形參:semid?semget函數返回值
???semnum?信號量數組下標,semnum=0表示第一個信號量
???cmd?控制命令:SETVAL 初始化信號量值
???????????IPC_RMID 刪除信號量,刪除只需要前三個參數即可
???????????GETVAL 獲取信號量值
???可變參數共用體類型(需要自己定義):
??????union semun {
?????????int val; /* 要設置的初始值 */
?????????struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
?????????unsigned short *array; /* Array for GETALL, SETALL */
?????????struct seminfo __buf; /* Buffer for IPC_INFO(Linux-specific) */
?????????};
返回值:失敗返回-1,成功根據cmd值返回
int semop(int semid, struct sembuf *sops, size_t nsops);
函數功能: 使用或者釋放信號量pv操作
形參:semid?semget函數返回值
???sops?信號量pv操作結構體
????struct sembuf sops
????{
?????unsigned short sem_num; /* 信號量集下標,0表示第一個信號量 */
?????short sem_op; /*>0則v操作,釋放信號量
???????????<0則p操作,使用信號量*/
?????short sem_flg; / 0 表示默認操作,沒有信號量可用就等待。IPC_NOWAIT 表示不等待。 */
????}
返回值:成功返回信號量標志符,失敗返回-1;

6.創建一個信號量示例

??(1)創建信號量

#include 
#include 
#include 
#include 
#include 
#include 
#include 
union semun 
{
   int  val;    /* 信號量值 */
   struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
   unsigned short  *array;  /* Array for GETALL, SETALL */
   struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */
};
int main(int argc,char *argv[])
{
	if(argc!=2)
	{
		printf("格式:./a.out <信號量值>\n");
		return 0;
	}
	key_t key=ftok("semget.c",1234);//產生鍵值
	if(key==-1)
	{
		printf("產生鍵值失敗res=%s\n",strerror(errno));
		return 0;
	}
	printf("key=%#x\n",key);
	int semid=semget(key,1,IPC_CREAT|0666);//創建1個信號量
	if(semid==-1)
	{
		printf("創建信號量集失敗res=%s\n",strerror(errno));
		return 0;
	}
	printf("semid=%d\n",semid);
	union semun  sem;
	sem.val=atoi(argv[1]);
	/*初始化信號量*/
	if(semctl(semid,0,SETVAL,sem))
	{
		printf("初始化信號量值失敗err=%s\n",strerror(errno));
		return 0;
	}
	/*獲取信號量*/
	int val=semctl(semid,0,GETVAL,NULL);
	printf("信號量值:%d\n",val);
	/*通過系統命令查看信號量詳細信息*/
	char buff[20];
	snprintf(buff,sizeof(buff),"ipcs -s -i %d",semid);
	system(buff);
	return 0;
}

??(2)使用信號量

#include 
#include 
#include 
#include 
#include 
#include 
#include 
union semun 
{
   int  val;    /* 信號量值 */
   struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
   unsigned short  *array;  /* Array for GETALL, SETALL */
   struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */
};
int main(int argc,char *argv[])
{
	if(argc!=2)
	{
		printf("格式:./a.out <使用信號值>\n");
		return 0;
	}
	key_t key=ftok("semget.c",1234);//產生鍵值
	if(key==-1)
	{
		printf("產生鍵值失敗res=%s\n",strerror(errno));
		return 0;
	}
	printf("key=%#x\n",key);
	int semid=semget(key,1,IPC_CREAT|0666);//創建1個信號量
	if(semid==-1)
	{
		printf("創建信號量集失敗res=%s\n",strerror(errno));
		return 0;
	}
	printf("semid=%d\n",semid);
	/*獲取信號量*/
	int val=semctl(semid,0,GETVAL,NULL);
	printf("信號量值:%d\n",val);
	/*pv操作*/
	struct sembuf sops=
	{
		.sem_num=0,//信號量下標
		.sem_op=atoi(argv[1]),
		.sem_flg=0//阻塞等待
	};
	int ret=semop(semid,&sops,1);
	printf("ret=%d\n",ret);
	/*獲取信號量*/
	val=semctl(semid,0,GETVAL,NULL);
	printf("信號量值:%d\n",val);
	return 0;
}
pYYBAGL_eEaAH_D3AAKPgdfERdw629.png#pic_center

7.創建多個信號量

??(1)創建多個信號量

#include 
#include 
#include 
#include 
#include 
#include 
#include 
union semun 
{
   int  val;    /* 信號量值 */
   struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
   unsigned short  *array;  /* Array for GETALL, SETALL */
   struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */
};
int main(int argc,char *argv[])
{
	if(argc!=4)
	{
		printf("格式:./a.out <信號量值1> <信號量值2> <信號量值3>\n");
		return 0;
	}
	key_t key=ftok("semget.c",1234);//產生鍵值
	if(key==-1)
	{
		printf("產生鍵值失敗res=%s\n",strerror(errno));
		return 0;
	}
	printf("key=%#x\n",key);
	int semid=semget(key,3,IPC_CREAT|0666);//創建3個信號量
	if(semid==-1)
	{
		printf("創建信號量集失敗res=%s\n",strerror(errno));
		return 0;
	}
	printf("semid=%d\n",semid);
	union semun  sem[3];
	sem[0].val=atoi(argv[1]);//初始化第一個信號量
	sem[1].val=atoi(argv[2]);//初始化第二個信號量
	sem[2].val=atoi(argv[3]);//初始化第三個信號量
	int i=0;
	for(i=0;i<3;i++)
	{
		/*初始化信號量*/
		if(semctl(semid,i,SETVAL,sem[i]))
		{
			printf("初始化信號量值失敗err=%s\n",strerror(errno));
			return 0;
		}
		/*獲取信號量*/
		int val=semctl(semid,i,GETVAL,NULL);
		printf("第%d個信號量值:%d\n",i,val);
	}
	/*通過系統命令查看信號量詳細信息*/
	system("ipcs -s");
	return 0;
}

??(2)使用多個信號量

#include 
#include 
#include 
#include 
#include 
#include 
#include 
union semun 
{
   int  val;    /* 信號量值 */
   struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
   unsigned short  *array;  /* Array for GETALL, SETALL */
   struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */
};
int main(int argc,char *argv[])
{
	if(argc!=2)
	{
		printf("格式:./a.out <使用信號值>\n");
		return 0;
	}
	key_t key=ftok("semget.c",1234);//產生鍵值
	if(key==-1)
	{
		printf("產生鍵值失敗res=%s\n",strerror(errno));
		return 0;
	}
	printf("key=%#x\n",key);
	int semid=semget(key,3,IPC_CREAT|0666);//創建3個信號量
	if(semid==-1)
	{
		printf("創建信號量集失敗res=%s\n",strerror(errno));
		return 0;
	}
	printf("semid=%d\n",semid);
	int i=0;
	/*獲取信號量*/
	for(i=0;i<3;i++)
	{
		/*獲取信號量*/
		int val=semctl(semid,i,GETVAL,NULL);
		printf("第%d個信號量值:%d\n",i,val);
	}
	/*pv操作*/
	
	struct sembuf sops[3]=
	{
		{
			.sem_num=0,//信號量下標
			.sem_op=atoi(argv[1]),
			.sem_flg=0//阻塞等待
		},
		{
			.sem_num=1,//信號量下標
			.sem_op=atoi(argv[1]),
			.sem_flg=0//阻塞等待
		},
		{
			.sem_num=2,//信號量下標
			.sem_op=atoi(argv[1]),
			.sem_flg=0//阻塞等待
		}
	};
	int ret=semop(semid,sops,3);//一次使用3個信號量
	printf("ret=%d\n",ret);
	/*獲取信號量*/
	/*獲取信號量*/
	for(i=0;i<3;i++)
	{
		/*獲取信號量*/
		int val=semctl(semid,i,GETVAL,NULL);
		printf("第%d個信號量值:%d\n",i,val);
	}
	return 0;
}

??(3)運行效果

poYBAGL_eEeAB3BeAAJ-UvQXGSQ340.png#pic_center

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11292

    瀏覽量

    209323
  • IPC
    IPC
    +關注

    關注

    3

    文章

    346

    瀏覽量

    51902
  • 進程
    +關注

    關注

    0

    文章

    203

    瀏覽量

    13960
收藏 人收藏

    評論

    相關推薦

    FreeRTOS信號量使用教程

    信號量是操作系統中重要的一部分,信號量一般用來進行資源管理和任務同步, FreeRTOS中信號量又分為二值信號量、 計數型信號量、互斥
    的頭像 發表于 12-19 09:22 ?3199次閱讀
    FreeRTOS<b class='flag-5'>信號量</b>使用教程

    linux操作系統進程通信設計

    用戶進程。我們可以從頭文件/usr/src/linux/include/linux/sem.h中看到內核用來維護信號量狀態的各個結構的定義。信號量
    發表于 04-16 09:17

    進程間通信 信號量

    定義:信號量是一個計數器,用于多進程對共享數據對象的存取訪問控制。為了獲得共享資源,進程需要執行下列操作信號量使用步驟:1:初始化信號量--
    發表于 07-20 10:15

    關于ucosii中信號量的問題

    我定義了一個信號量: OS_FLAG_GRP *FlagTest1;INT8U Flag_Error在任務初始化之前,創建:FlagTest1=OSFlagCreate((OS_FLAGS)0
    發表于 10-19 16:49

    芯靈思SinlinxA33開發板的Linux內核信號量學習

    用戶進程。我們可以從頭文件/usr/src/linux/include/linux/sem.h 中看到內核用來維護信號量狀態的各個結構的定義。信號量
    發表于 02-20 15:50

    芯靈思SinlinxA64開發板 Linux內核信號量學習

    信號量狀態的各個結構的定義。信號量是一個數據集合,用戶可以單獨使用這一合的每個元素。要調用的第一個函數是semget,用以獲得一個信號量ID。Li
    發表于 03-15 16:10

    linux多線程編程中,一次等待多個信號量怎么解決

    linux多線程(非進程)編程中,一次等待多個信號量怎么解決?并且等到信號量來了后,能判斷是那一個?功能如同window
    發表于 06-17 05:55

    你了解Linux 各類信號量

    內核信號量與用戶信號量,用戶信號量分為POXIS信號量和SYSTEMV信號量,POXIS信號量
    發表于 05-04 17:19 ?2515次閱讀
    你了解<b class='flag-5'>Linux</b> 各類<b class='flag-5'>信號量</b>?

    Linux IPC POSIX 信號量

    //獲得信號量sem的當前的值,放到sval中。如果有線程正在block這個信號量,sval可能返回兩個值,0或“-正在block的線程的數目”,Linux返回0//成功返回0,失敗返回-1設
    發表于 05-16 17:39 ?927次閱讀

    Linux IPC System V 信號量

    ?立即銷毀指定的信號量,調用的進程的的effective UID必須和信號量的創建者或所有者相匹配,或者這個
    發表于 04-02 14:46 ?327次閱讀

    Linux 多線程信號量同步

    直到系統將資源分配給該進程(進入等待隊列,一直等到資源輪到該進程)。V操作:如果在該信號量的等待隊列中有進程在等待資源,則喚醒一個阻塞進程;
    發表于 04-02 14:47 ?395次閱讀

    Linux信號量(2):POSIX 信號量

    上一章,講述了 SYSTEM V 信號量,主要運行于進程之間,本章主要介紹 POSIX 信號量:有名信號量、無名信號量。 POSIX
    的頭像 發表于 10-29 17:34 ?706次閱讀

    LINUX內核的信號量設計與實現

    控制路徑可以睡眠。我們從 LINUX內核信號量最直觀的設計/實現出發,通過一步步改進,揭示在x86平臺上完整的信號量設計/實現,然后探討在不同平臺上通用的信號量設計/實現。
    發表于 01-14 16:55 ?18次下載

    LINUX內核的信號量設計與實現

    控制路徑可以睡眠。我們從 LINUX內核信號量最直觀的設計/實現出發,通過一步步改進,揭示在x86平臺上完整的信號量設計/實現,然后探討在不同平臺上通用的信號量設計/實現。
    發表于 01-14 16:55 ?5次下載

    使用Linux信號量實現互斥點燈

    信號量常用于控制對共享資源的訪問,有計數型信號量和二值信號量之分。初始化時信號量值大于1的,就是計數型信號量,計數型
    的頭像 發表于 04-13 15:12 ?803次閱讀
    使用<b class='flag-5'>Linux</b><b class='flag-5'>信號量</b>實現互斥點燈
    主站蜘蛛池模板: 99福利在线| 中文字幕AV亚洲精品影视| 午夜日韩久久影院| 午夜婷婷精品午夜无码A片影院| 亚洲成AV人电影在线观看| 亚洲中久无码永久在线| 色狼亚洲色图| 男神插曲女生软件完整版| 成人午夜剧场| 国产一区在线观看免费| 久久久久婷婷国产综合青草| 蜜芽tv在线www| 少妇精品久久久一区二区三区| 亚洲AV无码国产精品色午夜情| 夜色女人香| bbwvideoa欧美老妇| 国产精品久久久久无码AV色戒| 簧片在线免费观看| 魔乳 堕乳漫画acg产卵| 受被三个攻各种道具PLAY| 一本之道高清视频在线观看| a久久99精品久久久久久蜜芽| 国产精品麻豆AV| 久久免费看视频| 色妺妺免费影院| 一线高清视频在线播放| 超碰caoporon最新视频| 黄色xxxxxx| 漂亮的保姆6在线观看中文| 亚洲国产五月综合网| 5566精品资源在线播放| 国产精品嫩草影院| 免费成人小视频| 亚洲成人精品| 99久热这里精品免费| 国产学生在线播放精品视频| 精品久久日日躁夜夜躁AV| 日本免费一区二区三区四区五六区| 亚洲国产在线精品国自产拍五月 | 亚洲精品婷婷无码成人A片在线| 伊人久久国产|