3、For Example
// 聯合體,用于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;
}
int main()
{
int sem_id; // 信號量集ID
key_t key;
pid_t pid;
// 獲取key值
if((key = ftok(".", 'z')) < 0)
{
perror("ftok error");
exit(1);
}
// 創建信號量集,其中只有一個信號量
if((sem_id = semget(key, 1, IPC_CREAT|0666)) == -1)
{
perror("semget error");
exit(1);
}
// 初始化:初值設為0資源被占用
init_sem(sem_id, 0);
if((pid = fork()) == -1)
perror("Fork Error");
else if(pid == 0) /子進程/
{
sleep(2);
printf("Process child: pid=%d\\n", getpid());
sem_v(sem_id); /釋放資源/
}
else /父進程/
{
sem_p(sem_id); /等待資源/
printf("Process father: pid=%d\\n", getpid());
sem_v(sem_id); /釋放資源/
del_sem(sem_id); /刪除信號量集/
}
return 0;
}
上面的例子如果不加信號量,則父進程會先執行完畢。這里加了信號量讓父進程等待子進程執行完以后再執行。
五、共享內存
共享內存(Shared Memory),指兩個或多個進程共享一個給定的存儲區。
1、特點
- 共享內存是最快的一種 IPC,因為進程是直接對內存進行存取。
- 因為多個進程可以同時操作,所以需要進行同步。
- 信號量+共享內存通常結合在一起使用,信號量用來同步對共享內存的訪問。
2、原型
// 創建或獲取一個共享內存:成功返回共享內存ID,失敗返回-1
intshmget(key_t key, size_t size, int flag);
// 連接共享內存到當前進程的地址空間:成功返回指向共享內存的指針,失敗返回-1
voidshmat(int shm_id, constvoid *addr, int flag);
// 斷開與共享內存的連接:成功返回0,失敗返回-1
intshmdt(void addr);
// 控制共享內存的相關信息:成功返回0,失敗返回-1
intshmctl(int shm_id, int cmd, struct shmid_ds *buf);
當用shmget函數創建一段共享內存時,必須指定其size;而如果引用一個已存在的共享內存,則將size指定為0 。
當一段共享內存被創建以后,它并不能被任何進程訪問。必須使用shmat函數連接該共享內存到當前進程的地址空間,連接成功后把共享內存區對象映射到調用進程的地址空間,隨后可像本地空間一樣訪問。
shmdt函數是用來斷開shmat建立的連接的。注意,這并不是從系統中刪除該共享內存,只是當前進程不能再訪問該共享內存而已。
shmctl函數可以對共享內存執行多種操作,根據參數 cmd 執行相應的操作。常用的是IPC_RMID(從系統中刪除該共享內存)。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
Linux
+關注
關注
87文章
11411瀏覽量
212233 -
IPC
+關注
關注
3文章
358瀏覽量
52661 -
進程間通信
+關注
關注
0文章
16瀏覽量
2496
發布評論請先 登錄
相關推薦
Linux現有的所有進程間IPC方式
在開始回答前,先簡單概括性地說說Linux現有的所有進程間IPC方式:1. **管道:**在創建時分配一個page大小的內存,緩存區大小比較有限;2. 消息隊列:信息復制兩次,額外的C
發表于 08-20 06:17
Linux進程間的五種通信方式介紹 3
進程間通信(IPC,InterProcess Communication)是指在不同進程之間傳播或交換信息。IPC的方式通常有管道(包括無名
Linux進程間的五種通信方式介紹 6
進程間通信(IPC,InterProcess Communication)是指在不同進程之間傳播或交換信息。IPC的方式通常有管道(包括無名
Linux進程間的五種通信方式介紹 5
進程間通信(IPC,InterProcess Communication)是指在不同進程之間傳播或交換信息。IPC的方式通常有管道(包括無名
評論