System V IPC


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鍵,程序如下:

View Code
 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個標識符值,程序如下:

View Code
 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的多數實現在有內在的內核限制,如消息隊列的最大數目、每個信號集的最大信號量數等等。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM