1、概述
System V IPC共有三種類型:System V消息隊列、System V 信號量、System V 共享內存區。 System V IPC操作函數如下:
2、key_t鍵和ftok函數
三種類型的IPC使用key_t值作為他們的名字,頭文件<sys/types.h>把key_t定義為一個整數,通常是一個至少32位的整數,由ftok函數賦予的。函數ftok把一個已存的路徑和一個整數標識符轉換成一個key_t值,稱為IPC鍵。函數原型如下:
#include <sys/types.h>#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id); //成功返回IPC鍵,出錯返回-1
寫個程序看看ftok是如何組合IPC鍵,程序如下:

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <sys/types.h> 5 #include <sys/ipc.h> 6 #include <sys/stat.h> 7 #include <errno.h> 8 9 typedef unsigned long u_long; 10 11 int main(int argc,char *argv[]) 12 { 13 struct stat st; 14 key_t key; 15 if(argc != 2) 16 { 17 printf("usage: ftok<pathname>"); 18 exit(0); 19 } 20 //獲取文件結構信息 21 if (stat(argv[1],&st) == -1) 22 { 23 perror("stat() error"); 24 exit(EXIT_FAILURE); 25 } 26 printf("st_dev : %lx,st_ino: %lx ",(u_long)st.st_dev,(u_long)st.st_ino); 27 //產生IPC鍵 28 if((key = ftok(argv[1],0x57)) == -1) 29 { 30 perror("ftok() error"); 31 exit(EXIT_FAILURE); 32 } 33 printf("key: %x\n",key); 34 exit(0); 35 }
在Ubuntu上程序測試結果如下:
可以看出在Linux上面IPC鍵使用的是id低8位,st_dev的低8位以及st_ino的低16位構成的。
3、ipc_perm結構
內核給每個IPC對象維護一個信息結構,內容跟內核給文件維護的信息類似。Unix下結構信息如下:
struct ipc_perm
{
key_t key; /* Key supplied to semget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short seq; /* Sequence number */
};
在Linux該結構信息如下:
參考http://linux.die.net/man/5/ipc
4、創建與打開IPC通道
對於key值,有兩種選擇:
(1)調用fotk函數,給它傳遞pathname和id。
(2)指定key為IPC_PRIVATE,保證會創建一個新的、唯一的IPC對象。
5、IPC權限
For semaphores (from sys/sem.h)
#define SEM_A 0200 /* alter permission */
#define SEM_R 0400 /* read permission */
For message queues (from sys/msg.h)
#define MSG_R 0400 /* read permission */
#define MSG_W 0200 /* write permission */
For shared memory (from sys/shm.h)
#define SHM_R 0400 /* read permission */
#define SHM_W 0200 /* write permission */
6、標識符重用
System V IPC 標識符是系統范圍的,不是特定於進程的。ipc_perm結構含有一個名為seq的變量,是內核為系統每個潛在的IPC對象維護的計數器,每當刪除一個IPC對象時,內核就遞增相應的槽位號,若溢出則循環到0。這樣避免短時間內重用System V IPC標識符,有助於確保過早終止的服務器重新啟動后不會重用標識符。寫個程序測試輸出有megget返回的前10個標識符值,程序如下:

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <sys/types.h> 5 #include <sys/ipc.h> 6 #include <sys/msg.h> 7 8 #define MSG_R 0400 /* read permission */ 9 #define MSG_W 0200 /* write permission */ 10 11 #define SVMSG_MODE (MSG_R | MSG_W | MSG_R >>3 | MSG_R >>6) 12 13 int main() 14 { 15 int i,msqid; 16 for(i=0;i<10;++i) 17 { 18 msqid = msgget(IPC_PRIVATE,SVMSG_MODE|IPC_CREAT); 19 printf("msqid = %d\n",msqid); 20 msgctl(msqid,IPC_RMID,NULL); 21 } 22 exit(0); 23 }
在Ubuntu上面測試結果如下:
7、ipcs和ipcrm程序
System V IPC的三種類型不是以文件系統中的路徑名標識的,不能使用ls和rm程序查看和刪除。而是同ipcs程序輸出System V IPC特性的各種信息,ipcrm則刪除一個System V 消息隊列、信號量或共享內存區。
ipcs - 分析消息隊列、共享內存和信號量
ipcs [-mqs] [-abcopt] [-C core] [-N namelist]
-m 輸出有關共享內存(shared memory)的信息
-q 輸出有關信息隊列(message queue)的信息
-s 輸出信號量(semaphore)的信息
輸出本機所有System V IPC消息如下:
ipcrm - 刪除ipc(清除共享內存信息)
ipcrm -m|-q|-s shm_id
-m 輸出有關共享內存(shared memory)的信息
-q 輸出有關信息隊列(message queue)的信息
-s 輸出信號量(semaphore)的信息
8、內核限制
System V IPC的多數實現在有內在的內核限制,如消息隊列的最大數目、每個信號集的最大信號量數等等。