Linux进程通信中IPC对象——IPC_PRIVATE与ftok
在linux中,可以使用IPC對象來進行進程間通信。IPC對象存在于內核中,多進程可以操作同一個IPC對象。每個IPC對象都有一個唯一的編號,該編號是由系統分配的。那么不同的進程如何知道這個編號,進而通過它進行通信呢?下面以共享內存為例,進行分析。
方法一:通過ftok函數,產生相同的鍵值。
假設,進程p1創建了共享內存。可以在創建時,調用ftok函數,得到一個key值,調用shmget函數,該函數會返回所創建共享內存的編號,并將key和編號關聯起來。若進程p2想利用這個共享內存和p1進程通信,也可以調用ftok函數,得到同樣的key,再根據key值,調用shmget函數,就可以獲得該共享內存的編號。該過程可以通過下面的圖來表達。
ftok函數原型如下:
????????????????#include < sys/types.h>
????????????????#include < sys/ipc.h>
????????????????key_t ftok(const char *pathname, int proj_id);
第一個參數pathname,是一個存在的文件或目錄名;
第二個參數proj_id,是非0整數(一般用i節點號)
該函數會返回一個key值,先運行的進程根據key來創建對象,后運行的進程根據key來打開對象。示意圖如下:
使用 ftok創建共享內存,毫無關系的進程,可以通過得到同樣的key,來操作同一個共享內存,對共享內存進行讀寫時,需要利用信號量進行同步或互斥。
方法二:使用IPC_PRIVATE對象
使用IPC_PRIVATE創建的IPC對象, key值屬性為0,和IPC對象的編號就沒有了對應關系。這樣毫無關系的進程,就不能通過key值來得到IPC對象的編號(因為這種方式創建的IPC對象的key值都是0)。因此,這種方式產生的IPC對象,和無名管道類似,不能用于毫無關系的進程間通信。但也不是一點用處都沒有,仍然可以用于有親緣關系的進程間通信。示例程序如下:
#include < stdio.h>
#include < stdlib.h>
#include < errno.h>
#include < sys/ipc.h>
#include < sys/types.h>
#include < sys/shm.h>
#include < string.h>
#define MAXSIZE 1024int main(){int shmid;char *p = NULL;pid_t pid;key_t key;if ((key = ftok(".", 'a')) == -1){perror("ftok");exit(-1);}if ((shmid = shmget(IPC_PRIVATE, MAXSIZE, 0666)) == -1){perror("shmget");exit(-1);}if ((pid = fork()) == -1){perror("fork");exit(-1);}if (pid == 0){if ((p = shmat(shmid, NULL, 0)) == (void *)-1){perror("shmat");exit(-1);}strcpy(p, "hello\n");system("ipcs -m");if (shmdt(p) == -1){perror("shmdt");exit(-1);}system("ipcs -m");}else{getchar();if((p = shmat(shmid, NULL, 0)) == (void *)-1){perror("shmat");exit(-1);}printf("%s\n", (char *)p);if (shmctl(shmid, IPC_RMID, NULL) == -1){perror("RM");exit(-1);}}return 0;
}
該程序中,父進程使用IPC_PRIVATE方式創建了共享內存,然后fork產生了子進程,由于子進程是復制父進程的方式產生的,因此,子進程也可以操作共享內存。子進程往共享內存里寫了內容后,父進程可以讀到。
轉自https://blog.csdn.net/niepangu/article/details/55271708
總結
以上是生活随笔為你收集整理的Linux进程通信中IPC对象——IPC_PRIVATE与ftok的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux文件中的stat结构
- 下一篇: 电视剧荡寇里的龟田博士是谁