3、For Example
下面這個例子,使用了【共享內(nèi)存+信號量+消息隊列】的組合來實現(xiàn)服務(wù)器進程與客戶進程間的通信。
- 共享內(nèi)存用來傳遞數(shù)據(jù);
- 信號量用來同步;
- 消息隊列用來 在客戶端修改了共享內(nèi)存后 通知服務(wù)器讀取。
server.c
// 消息隊列結(jié)構(gòu)
struct msg_form {
long mtype;
char mtext;
};
// 聯(lián)合體,用于semctl初始化
union semun
{
int val; /for SETVAL/
struct semid_ds buf;
unsigned short *array;
};
// 初始化信號量
int init_sem(int sem_id, int value)
{
union semun tmp;
tmp.val = value;
if(semctl(sem_id, 0, SETVAL, tmp) == -1)
{
perror("Init Semaphore Error");
return -1;
}
return 0;
}
// P操作:
// 若信號量值為1,獲取資源并將信號量值-1
// 若信號量值為0,進程掛起等待
int sem_p(int sem_id)
{
struct sembuf sbuf;
sbuf.sem_num = 0; /序號/
sbuf.sem_op = -1; /P操作/
sbuf.sem_flg = SEM_UNDO;
if(semop(sem_id, &sbuf, 1) == -1)
{
perror("P operation Error");
return -1;
}
return 0;
}
// V操作:
// 釋放資源并將信號量值+1
// 如果有進程正在掛起等待,則喚醒它們
int sem_v(int sem_id)
{
struct sembuf sbuf;
sbuf.sem_num = 0; /序號/
sbuf.sem_op = 1; /V操作/
sbuf.sem_flg = SEM_UNDO;
if(semop(sem_id, &sbuf, 1) == -1)
{
perror("V operation Error");
return -1;
}
return 0;
}
// 刪除信號量集
int del_sem(int sem_id)
{
union semun tmp;
if(semctl(sem_id, 0, IPC_RMID, tmp) == -1)
{
perror("Delete Semaphore Error");
return -1;
}
return 0;
}
// 創(chuàng)建一個信號量集
intcreat_sem(key_t key)
{
int sem_id;
if((sem_id = semget(key, 1, IPC_CREAT|0666)) == -1)
{
perror("semget error");
exit(-1);
}
init_sem(sem_id, 1); /初值設(shè)為1資源未占用/
return sem_id;
}
int main()
{
key_t key;
int shmid, semid, msqid;
char shm;
char data[] = "this is server";
struct shmid_ds buf1; /用于刪除共享內(nèi)存/
struct msqid_ds buf2; /用于刪除消息隊列/
struct msg_form msg; /消息隊列用于通知對方更新了共享內(nèi)存/
// 獲取key值
if((key = ftok(".", 'z')) < 0)
{
perror("ftok error");
exit(1);
}
// 創(chuàng)建共享內(nèi)存
if((shmid = shmget(key, 1024, IPC_CREAT|0666)) == -1)
{
perror("Create Shared Memory Error");
exit(1);
}
// 連接共享內(nèi)存
shm = (char*)shmat(shmid, 0, 0);
if((int)shm == -1)
{
perror("Attach Shared Memory Error");
exit(1);
}
// 創(chuàng)建消息隊列
if ((msqid = msgget(key, IPC_CREAT|0777)) == -1)
{
perror("msgget error");
exit(1);
}
// 創(chuàng)建信號量
semid = creat_sem(key);
// 讀數(shù)據(jù)
while(1)
{
msgrcv(msqid, &msg, 1, 888, 0); /讀取類型為888的消息/
if(msg.mtext == 'q') /quit - 跳出循環(huán)/
break;
if(msg.mtext == 'r') /read - 讀共享內(nèi)存/
{
sem_p(semid);
printf("%s\\n",shm);
sem_v(semid);
}
}
// 斷開連接
shmdt(shm);
/刪除共享內(nèi)存、消息隊列、信號量/
shmctl(shmid, IPC_RMID, &buf1);
msgctl(msqid, IPC_RMID, &buf2);
del_sem(semid);
return 0;
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。
舉報投訴
-
Linux
+關(guān)注
關(guān)注
87文章
11207瀏覽量
208717 -
IPC
+關(guān)注
關(guān)注
3文章
337瀏覽量
51772 -
進程間通信
+關(guān)注
關(guān)注
0文章
16瀏覽量
2425
發(fā)布評論請先 登錄
相關(guān)推薦
Linux下進程間如何實現(xiàn)共享內(nèi)存通信
這次我們來講一下Linux進程通信中重要的通信方式:共享內(nèi)存作為Linux軟件開發(fā)攻城獅,
發(fā)表于 04-26 17:14
?672次閱讀
Linux下進程間通信
華清遠見嵌入式linux學(xué)習(xí)資料《Linux下進程間通信》,通過前面的學(xué)習(xí),讀者已經(jīng)知道了進程是
發(fā)表于 09-04 10:07
Linux現(xiàn)有的所有進程間IPC方式
在開始回答前,先簡單概括性地說說Linux現(xiàn)有的所有進程間IPC方式:1. **管道:**在創(chuàng)建時分配一個page大小的內(nèi)存,緩存區(qū)大小比較有限;2. 消息隊列:信息復(fù)制兩次,額外的C
發(fā)表于 08-20 06:17
哪些方式可以實現(xiàn)Linux系統(tǒng)下的進程間通信
哪些方式可以實現(xiàn)Linux系統(tǒng)下的進程間通信?進程與線程有哪些不同之處呢?
發(fā)表于 12-24 06:38
Linux進程間的五種通信方式介紹 3
進程間通信(IPC,InterProcess Communication)是指在不同進程之間傳播或交換信息。IPC的方式通常有管道(包括無名
Linux進程間的五種通信方式介紹 4
進程間通信(IPC,InterProcess Communication)是指在不同進程之間傳播或交換信息。IPC的方式通常有管道(包括無名
Linux進程間的五種通信方式介紹 6
進程間通信(IPC,InterProcess Communication)是指在不同進程之間傳播或交換信息。IPC的方式通常有管道(包括無名
評論