
POSIX?線程中的同步用的是無名信號量
進程間的同步使用的是IPC?對象[信號燈集]
信號燈集:信號燈集合,每一個信號燈都可以用來表示一類資源,其值表示資源的個數
(1)創建信號燈集
int?semget(key_t?key,?int?nsems,?int?semflg);
參數:
@key?IPC_PRIVATE?,?ftok()
@nsems?信號燈集中信號燈的個數
@semflg?IPC_CREAT?|?0666,IPC_CREAT?|?IPC_EXCL
返回值:
成功返回ID,失敗返回-1
(2)初始化信號燈集中信號燈的值
int?semctl(int?semid,?int?semnum,?int?cmd,?...);
參數:
@semid?信號燈集的ID
@semnum?信號燈的編號[編號從0開始]
@cmd?SETVAL[設置信號燈的值]?,GETVAL(獲取信號燈的值),IPC_RMID[刪除信號燈集]
返回值:
成功返回0,失敗返回-1
思考:將信號燈集中的1號信號燈初始化為1?
union?semun?{
int?val;?/*?Value?for?SETVAL?*/
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)?*/
};
void?init_sem_value(int?sem_id,int?sem_num,int?value)
{
union?semun?sem_val;
sem_val.val?=?value;
if(semctl(sem_id,sem_num,SETVAL,sem_val)?<?0)
{
...
}
return?;
}
(3)PV操作
int?semop(int?semid,?struct?sembuf?*sops,?unsigned?nsops);
功能:完成PV操作
參數:
@semid?信號燈集的ID
@sops?操作方式結構體首地址
@nsops?操作信號燈的個數
返回值:
成功返回0,失敗返回-1
struct?sembuf
{
unsigned?short?sem_num;?/*?semaphore?number?*/
short?sem_op;?/*?semaphore?operation?*/
short?sem_flg;?/*?operation?flags?*/
};
sem_op?:
<1>0?等待信號燈的值變成0
<2>1?釋放資源,V操作
<3>-1?申請資源,P操作
sem_flg:
0?:?阻塞方式
IPC_NOWAIT?:?非阻塞方式調用
SEM_UNDO?:?進程結束的時候,它申請的資源自動釋放
void?P(int?sem_id,int?sem_num)
{
struct?sembuf?sem;
sem.sem_num?=?sem_num;
sem.sem_op?=?-1;
sem.sem_flg?=?0;
if(semop(sem_id,&sem,1)?<?0)
{
....
}
}
void?V(int?sem_id,int?sem_num)
{
struct?sembuf?sem;
sem.sem_num?=?sem_num;
sem.sem_op?=?1;
sem.sem_flg?=?0;
if(semop(sem_id,&sem,1)?<?0)
{
....
}
}
練習:A,B通過信號燈集同步對共享內存操作
讓創建信號燈集的進程,初始化信號燈的值?,如果信號燈集已經存在則不初始化
sem_id?=?semget(key,2,IPC_CREAT?|?IPC_EXCL?|?0666);
if(sem_id?<?0)//信號燈集已經,不初始化信號燈值
{
sem_id?=?semget(key,2,IPC_CREAT?|?0666);
}else{
//初始化信號燈集中信號燈的值
}
嵌入式物聯網需要學的東西真的非常多,千萬不要學錯了路線和內容,導致工資要不上去!
無償分享大家一個資料包,差不多150多G。里面學習內容、面經、項目都比較新也比較全!某魚上買估計至少要好幾十。
(點擊找小助理0元領取)掃碼進群領資料https://s.pdb2.com/pages/20230519/16QijNiGb32IFIn.html