国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Linux:淺談信號量

2019-11-08 03:28:03
字體:
來源:轉載
供稿:網友

1.信號量的概念。 信號量的本質是一種數據操作鎖,它本?身不具有數據交換的功能,而是通過控制其他的通信資源(文件,外部設備)來實現進程間通信,它本?身只是一種外部資源的標識。信號量在此過程中負責數據操作的互斥、同步等功能。 當請求一個使用信號量來表示的資源時,進程需要先讀取信號量的值來判斷資源是否可用。大于0,資源可以請求,等于0,無資源可用,進程會進?入睡眠狀態直至資源可用。 當進程不再使用一個信號量控制的共享資源時,信號量的值+1,對信號量的值進行的增減 操作均為原子操作,這是由于信號量主要的作用是維護資源的互斥或多進程的同步訪問。 而在信號量的創建及初始化上,不能保證操作均為原子性。 2.信號量是如何工作的 由于信號量只能進?行兩種操作等待和發送信號,即P(sv)和V(sv),他們的?行為是這樣的: P(sv):如果sv的值?大于零,就給它減1;如果它的值為零,就掛起該進程的執?行 V(sv):如果有其他進程因等待sv?而被掛起,就讓它恢復運?行,如果沒有進程因等待sv?而掛 起,就給它加1. 3.相關函數  函數原型:int semget(key_t key,int nsems,int semflg);  參數解釋: key:所創建或打開信號量集的鍵值。需要是唯一的非零整數。   nsems:創建的信號量集中的信號量的個數,該參數只在創建信號量集時有效。幾乎總是取值為1.   flag:調用函數的操作類型,也可用于設置信號量集的訪問權限,用或來表示。

  功能描述   獲取與某個鍵關聯的信號量集標識。信號量集被建立的情況有兩種:   1.如果鍵的值是ipC_PRIVATE。   2.或者鍵的值不是IPC_PRIVATE,并且鍵所對應的信號量集不存在,同時標志中指定IPC_CREAT。   當調用semget創建一個信號量時,他的相應的semid_ds結構被初始化。ipc_perm中各個量被設置為相應   值:   sem_nsems被設置為nsems所示的值;   sem_otime被設置為0;   sem_ctime被設置為當前時間。 函數原型:int semop( int semid, struct sembuf semoparray[], size_t nops ); 參數解釋: 參數semid是一個通過semget函數返回的一個信號量標識符 參數nops標明了參數semoparray所指向數組中的元素個數 參數semoparray是一個struct sembuf結構類型的數組指針, 結構sembuf來說明所要執行的操作,其成員如下: 這里寫圖片描述 其中sem_flg說明函數semop的行為。通常被設置為SEM_UNDO。它將使得操作系統跟著當前進程對這個信號量的修改情況,如果這個進程在沒有釋放該信號量的情況下終止,操作系統將自動釋放該進程持有的信號量。

函數原型:int semctl(int semid,int semnum,int cmd,…); 參數解釋: sem_id是由semget返回的信號量標識符。 sem_num與前面一個函數相同。 cmd:表示將要采取的動作。 如果有第四個參數,一般為聯合體semun,成員如下: 這里寫圖片描述

信號量使用的簡單示例: 我們創建一個進程,代碼如下:

#include"head.h"#include<unistd.h>#include<sys/wait.h>int main(){ int sem_id = my_semget(1); initial(sem_id, 0); pid_t id = fork();//創建一個子進程 if (0 == id){ while(1){ //上鎖 if ( sem_p(sem_id, 0) == -1){ perror("children p error"); exit(0); } usleep(10200); printf("A"); fflush(stdout); usleep(23043); printf("A"); fflush(stdout); if ( sem_v(sem_id,0) == -1){ perror("children v error"); exit(0); } } } else{ while(1){ //上鎖 if ( sem_p(sem_id, 0) == -1){ perror("father p error"); exit(0); } usleep(10200); usleep(16200); printf("B"); fflush(stdout); usleep(33043); printf("B"); fflush(stdout); if ( sem_v(sem_id,0) == -1){ perror("father v error"); exit(0); } } int stat = 0; wait(&stat); }}

在沒有信號量之前,因為有睡眠延時,系統會隨機打印A和B,如: 這里寫圖片描述 添加信號量之后,因為A進程在信號量上鎖后,sv值變為0,則B進程會掛起,直到A進程解鎖,則系統會有規律的打印A和B。 這里寫圖片描述

head.h:#ifndef _HEAD_#define _HEAD_#include<stdio.h>#include<stdlib.h>#include<sys/sem.h>#include<sys/types.h>#include<sys/ipc.h>#define _PATH "."#define _NUM 0x98union semun { int val; // 使?用的值 struct semid_ds *buf; // IPC_STAT、IPC_SET 使?用緩存區 unsigned short *array; // GETALL,、SETALL 使?用的數組 struct seminfo *__buf; // IPC_INFO(linux特有) 使?用緩存區};int my_semget(int sem_num);int getsem();int initial(int sem_id, int which);int sem_p(int sem_id, int which);int sem_v(int sem_id, int which);int destroy(int sem_id);#endifhead.c:#include "head.h"#include<string.h>int static semgeting(int sem_num, int flag){ key_t key = ftok(_PATH, _NUM); return semget(key,sem_num, flag);}int static op_chang(int sem_id, int which, int op){ sembuf sem_t; memset(&sem_t, 0, sizeof(sembuf)); sem_t.sem_num = which; sem_t.sem_op = op; sem_t.sem_flg = 0; return semop(sem_id, &sem_t,1);}int my_semget(int sem_num){ return semgeting(sem_num, IPC_CREAT|IPC_EXCL|0666);}int getsem(){ return semgeting(0, 0);}int initial(int sem_id, int which){ semun sem_t; sem_t.val = 1; return semctl(sem_id, which, SETVAL, sem_t);}int sem_p(int sem_id, int which){ sembuf sem_t; return op_chang(sem_id, which,-1); }int sem_v(int sem_id, int which){ return op_chang(sem_id, which, 1); }int destroy(int sem_id){ return semctl(sem_id, 0, IPC_RMID, NULL);}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 田阳县| 涟源市| 德化县| 获嘉县| 潍坊市| 小金县| 桑日县| 会同县| 兴仁县| 离岛区| 马鞍山市| 汉阴县| 昌宁县| 盐山县| 涪陵区| 岑溪市| 浦江县| 时尚| 聊城市| 本溪| 边坝县| 平谷区| 双峰县| 图木舒克市| 天气| 阿克苏市| 临汾市| 高安市| 上栗县| 孝义市| 宽甸| 从化市| 阿拉善盟| 涿鹿县| 古蔺县| 津南区| 闻喜县| 海口市| 河池市| 鄢陵县| 乐平市|