前些天看到有个博主写博客采用问答式的叙述方法:把很多知识点通过一问一答的形式把文章串起来,我觉得这种形式不错,便于突出重点。后面我也做下尝试,一边写写博客,一边回顾一下自己对IPC进程通信的认识。

Q:这些例子来自哪?

A:来自IBM的文档库,具体地址可以参考我的这篇文章 http://blog.csdn.net/lzx_bupt/article/details/7651207,汇总了这几天我看的进程通信的资料。

 

Q:IBM原文都写过了,为什么还要在这里再写一遍?

A:IBM原文挺经典的,我这里还是建议大家看看,但是原文例子有些编译不通过的地方,需要做适当修改才能运行。另外那些例子比较早了,在现在的系统上运行结果不一定和文章描述一致。最后就是,原文对例子中的语句注释不够详细,不如再写一遍,加深对例子的认识,同时多学习点编程知识。

 

Q:代码里怎么那么多注释?

A:我本来想少写点注释的,并且打算用自己的话写,不过我发现系统编程手册给的解释特别好,而且已经很精简了,其他网站给的说明还没有手册的完整,所以干脆直接贴手册的内容吧。所以会看到注释比代码还多。。。,如果你不想看注释,直接把代码粘到本地,删除注释就一目了然了。

 

Q:例子能保证编译么,可以开始了?

A:都是自己编译通过的,让我们开始吧~

 

IPC共享内存-----系统V方式编程实例

该实例包含两个程序:map_v_write.cpp和map_v_read.cpp,分别编译后先创建一个文件名为myshm,这个文件是生成IPC KEY而用的,代码里有描述。之后先运行write程序,再运行read程序,观察结果。 

  1. /* 文件:map_v_write.cpp 
  2.    描述:和map_v_read.cpp文件配合完成系统V共享内存编程实验 
  3.  */  
  4. //#include   
  5. //#include //注释掉的两个头文件是IPC最基本的,但在shm.h中include过了  
  6. #include //系统V共享内存函数shmget shmat shmdt  
  7.   
  8. #include //memcpy  
  9. #include //perror  
  10. #include //errno  
  11.   
  12. //共享内存通信多采用结构体数据表达信息,任意定义  
  13. typedef struct{  
  14.     char name[4];  
  15.     int age;  
  16. }people;  
  17.   
  18. main(int argc, char** argv)  
  19. {  
  20.     int shm_id,i;  
  21.     key_t key;//保存ftok函数返回值  
  22.     char temp;  
  23.     people *p_map;  
  24.   
  25.     //创建IPC键值  
  26.     char* name = "./myshm";//务必指定存在的文件  
  27.     key = ftok(name, 1);//参数尽量别用0  
  28. /*   man ftok: 
  29.  
  30. NAME 
  31.      ftok - generate an IPC key 
  32.  
  33. SYNOPSIS 
  34.      #include  
  35.  
  36.      key_t ftok(const char *path, int id); 
  37.  
  38. DESCRIPTION 
  39.      The ftok() function returns a key based on path and id  that 
  40.      is  usable  in  subsequent calls to msgget(2), semget(2) and 
  41.      shmget(2). The path argument must  be  the  pathname  of  an 
  42.      existing file that the process is able to  stat(2). 
  43.  
  44.      The ftok() function will return the same key value  for  all 
  45.      paths  that name the same file, when called with the same id 
  46.      value, and will return different key values when called with 
  47.      different id values. 
  48.  
  49.      If the file named by path is removed while still referred to 
  50.      by a key, a call to ftok() with the same path and id returns 
  51.      an error. If the same file is  recreated,  then  a  call  to 
  52.      ftok()  with the same path and id is likely to return a dif- 
  53.      ferent key. 
  54.  
  55.      Only the low  order  8-bits  of  id  are  significant.   The 
  56.      behavior of ftok() is unspecified if these bits are 0. 
  57.  
  58. RETURN VALUES 
  59.      Upon successful completion, ftok() returns  a  key.   Other- 
  60.      wise,  ftok()  returns  (key_t)-1 and sets errno to indicate 
  61.      the error. 
  62. */  
  63.     perror("ftok:");//打印errno, 参考附录errno定义  
  64. /*  man perror 
  65.  
  66. NAME 
  67.      perror, errno - print system error messages 
  68.  
  69. SYNOPSIS 
  70.      #include  
  71.  
  72.      void perror(const char *s); 
  73.      #include  
  74.      int errno; 
  75.  
  76. DESCRIPTION 
  77.      The perror() function produces a  message  on  the  standard 
  78.      error  output  (file descriptor 2) describing the last error 
  79.      encountered during a call to a system or  library  function. 
  80.      The  argument string s is printed, followed by a colon and a 
  81.      blank, followed by the message and a NEWLINE character.   If 
  82.      s is a null pointer or points to a null string, the colon is 
  83.      not printed. The argument string should include the name  of 
  84.      the  program  that  incurred  the error. The error number is 
  85.      taken from the external variable errno, which  is  set  when 
  86.      errors  occur  but  not cleared when non-erroneous calls are 
  87.      made. See  intro(2). 
  88.  
  89. */  
  90.   
  91.     //获取共享内存ID  
  92.     shm_id=shmget(key,4096,IPC_CREAT|00666);//give the permissions  
  93.     perror("shmget:");  
  94. /*  man shmget: 
  95.  
  96. NAME 
  97.      shmget - get shared memory segment identifier 
  98.  
  99. SYNOPSIS 
  100.      #include  
  101.      #include  
  102.      #include  
  103.  
  104.      int shmget(key_t key, size_t size, int shmflg); 
  105.  
  106. DESCRIPTION 
  107.      The shmget() function returns the shared  memory  identifier 
  108.      associated with key. 
  109.  
  110.      A shared memory identifier and associated data structure and 
  111.      shared  memory segment of at least size bytes (see intro(2)) 
  112.      are created for key if one of the following are true: 
  113.  
  114.         o  The key argument is equal to IPC_PRIVATE. 
  115.  
  116.         o  The key argument does not already have a shared memory 
  117.            identifier  associated with it, and (shmflg&IPC_CREAT) 
  118.            is true. 
  119.  
  120.      Upon creation, the data structure associated  with  the  new 
  121.      shared memory identifier is initialized as follows: 
  122.  
  123.         o  The    values    of    shm_perm.cuid,    shm_perm.uid, 
  124.            shm_perm.cgid,  and  shm_perm.gid are set equal to the 
  125.            effective user ID  and  effective  group  ID,  respec- 
  126.            tively, of the calling process. 
  127.  
  128.         o  The access permission bits of  shm_perm.mode  are  set 
  129.            equal   to  the  access  permission  bits  of  shmflg. 
  130.            shm_segsz is set equal to the value of size. 
  131.  
  132.         o  The values  of  shm_lpid,  shm_nattch  shm_atime,  and 
  133.            shm_dtime are set equal to 0. 
  134.  
  135.         o  The shm_ctime is set equal to the current time. 
  136.  
  137.      Shared memory segments must be explicitly removed after  the 
  138.      last reference to them has been removed. 
  139.  
  140. RETURN VALUES 
  141.      Upon   successful   completion,   a   non-negative   integer 
  142.      representing  a shared memory identifier is returned. Other- 
  143.      wise, -1 is returned and errno is set to indicate the error. 
  144. */  
  145.   
  146.     p_map=(people*)shmat(shm_id,NULL,0);  
  147.     perror("shmat:");  
  148. /* 
  149. NAME 
  150.      shmop, shmat, shmdt - shared memory operations 
  151.  
  152. SYNOPSIS 
  153.      #include  
  154.      #include  
  155.  
  156.      void *shmat(int shmid, const void *shmaddr, int shmflg); 
  157.  
  158.   Default 
  159.      int shmdt(char *shmaddr); 
  160.  
  161.   Standard conforming 
  162.      int shmdt(const void *shmaddr); 
  163.  
  164. DESCRIPTION 
  165.      The shmat() function  attaches  the  shared  memory  segment 
  166.      associated  with  the  shared memory identifier specified by 
  167.      shmid to the data segment of the calling process.     
  168. */      
  169.     //往内存写入数据  
  170.     temp='a';  
  171.     for(i = 0;i<10;i++)  
  172.     {  
  173.         temp+=1;  
  174.         memcpy((*(p_map+i)).name,&temp,1);  
  175.         (*(p_map+i)).age=20+i;  
  176.     }  
  177.   
  178.     //unlink共享内存  
  179.     shmdt((char*)p_map);//这里可以去掉char*编译试试,我这里去掉后编译不通过,待研究  
  180.     perror("shmdt:");  
  181. /* 
  182.      The shmdt() function detaches  from  the  calling  process's 
  183.      data  segment  the  shared  memory  segment  located  at the 
  184.      address  specified  by  shmaddr.  If  the   application   is 
  185.      standard-conforming (see standards(5)), the shmaddr argument 
  186.      is of type const void *. Otherwise it is of type char *. 
  187. */  
  188.   
  189. }  

读端的程序用到的API和写端一样,就略去注释了

  1. /* 文件:map_v_read.cpp 
  2.    描述:和map_v_write.cpp文件配合完成系统V共享内存编程实验 
  3.  */  
  4. #include   
  5. #include   
  6.   
  7. #include   
  8. #include   
  9.   
  10. //读端程序要和写端程序保持一致,这样才能互相通信  
  11. //定义数据结构  
  12. typedef struct{  
  13.     char name[4];  
  14.     int age;  
  15. } people;  
  16.   
  17. main(int argc, char** argv)  
  18. {  
  19.     int shm_id,i;  
  20.     key_t key;  
  21.     people *p_map;  
  22.       
  23.     //create shm file and get key  
  24.     char* name = "./myshm";  
  25.     key = ftok(name,1);  
  26.     perror("ftok:");  
  27.       
  28.     //get shm  
  29.     shm_id = shmget(key,4096,IPC_CREAT);  
  30.     perror("shmget:");  
  31.       
  32.     //link the shm  
  33.     p_map = (people*)shmat(shm_id,NULL,0);  
  34.     perror("shmat:");  
  35.     for(i = 0;i<10;i++)  
  36.     {  
  37.         printf( "name:%s\n",(*(p_map+i)).name );  
  38.         printf( "age %d\n",(*(p_map+i)).age );  
  39.     }  
  40.       
  41.     //unlink  
  42.     shmdt((char*)p_map);  
  43.     perror("shmdt:");  
  44. }  


 最后贴一下errno.h定义,据此可以找到错误原因

  1. #define EPERM   1       /* Not super-user                       */  
  2. #define ENOENT  2       /* No such file or directory            */  
  3. #define ESRCH   3       /* No such process                      */  
  4. #define EINTR   4       /* interrupted system call              */  
  5. #define EIO     5       /* I/O error                            */  
  6. #define ENXIO   6       /* No such device or address            */  
  7. #define E2BIG   7       /* Arg list too long                    */  
  8. #define ENOEXEC 8       /* Exec format error                    */  
  9. #define EBADF   9       /* Bad file number                      */  
  10. #define ECHILD  10      /* No children                          */  
  11. #define EAGAIN  11      /* Resource temporarily unavailable     */  
  12. #define ENOMEM  12      /* Not enough core                      */  
  13. #define EACCES  13      /* Permission denied                    */  
  14. #define EFAULT  14      /* Bad address                          */  
  15. #define ENOTBLK 15      /* Block device required                */  
  16. #define EBUSY   16      /* Mount device busy                    */  
  17. #define EEXIST  17      /* File exists                          */  
  18. #define EXDEV   18      /* Cross-device link                    */  
  19. #define ENODEV  19      /* No such device                       */  
  20. #define ENOTDIR 20      /* Not a directory                      */  
  21. #define EISDIR  21      /* Is a directory                       */  
  22. #define EINVAL  22      /* Invalid argument                     */  
  23. #define ENFILE  23      /* File table overflow                  */  
  24. #define EMFILE  24      /* Too many open files                  */  
  25. #define ENOTTY  25      /* Inappropriate ioctl for device       */  
  26. #define ETXTBSY 26      /* Text file busy                       */  
  27. #define EFBIG   27      /* File too large                       */  
  28. #define ENOSPC  28      /* No space left on device              */  
  29. #define ESPIPE  29      /* Illegal seek                         */  
  30. #define EROFS   30      /* Read only file system                */  
  31. #define EMLINK  31      /* Too many links                       */  
  32. #define EPIPE   32      /* Broken pipe                          */  
  33. #define EDOM    33      /* Math arg out of domain of func       */  
  34. #define ERANGE  34      /* Math result not representable        */  
  35. #define ENOMSG  35      /* No message of desired type           */  
  36. #define EIDRM   36      /* Identifier removed                   */  
  37. #define ECHRNG  37      /* Channel number out of range          */  
  38. #define EL2NSYNC 38     /* Level 2 not synchronized             */  
  39. #define EL3HLT  39      /* Level 3 halted                       */  
  40. #define EL3RST  40      /* Level 3 reset                        */  
  41. #define ELNRNG  41      /* Link number out of range             */  
  42. #define EUNATCH 42      /* Protocol driver not attached         */  
  43. #define ENOCSI  43      /* No CSI structure available           */  
  44. #define EL2HLT  44      /* Level 2 halted                       */  
  45. #define EDEADLK 45      /* Deadlock condition.                  */  
  46. #define ENOLCK  46      /* No record locks available.           */  
  47. #define ECANCELED 47    /* Operation canceled                   */  
  48. #define ENOTSUP 48      /* Operation not supported              */  
  49.   
  50. /* Filesystem Quotas */  
  51. #define EDQUOT  49      /* Disc quota exceeded                  */  
  52.   
  53. /* Convergent Error Returns */  
  54. #define EBADE   50      /* invalid exchange                     */  
  55. #define EBADR   51      /* invalid request descriptor           */  
  56. #define EXFULL  52      /* exchange full                        */  
  57. #define ENOANO  53      /* no anode                             */  
  58. #define EBADRQC 54      /* invalid request code                 */  
  59. #define EBADSLT 55      /* invalid slot                         */  
  60. #define EDEADLOCK 56    /* file locking deadlock error          */  
  61.   
  62. #define EBFONT  57      /* bad font file fmt                    */  
  63.   
  64. /* Interprocess Robust Locks */  
  65. #define EOWNERDEAD      58      /* process died with the lock */  
  66. #define ENOTRECOVERABLE 59      /* lock is not recoverable */  
  67.   
  68. /* stream problems */  
  69. #define ENOSTR  60      /* Device not a stream                  */  
  70. #define ENODATA 61      /* no data (for no delay io)            */  
  71. #define ETIME   62      /* timer expired                        */  
  72. #define ENOSR   63      /* out of streams resources             */  
  73.   
  74. #define ENONET  64      /* Machine is not on the network        */  
  75. #define ENOPKG  65      /* Package not installed                */  
  76. #define EREMOTE 66      /* The object is remote                 */  
  77. #define ENOLINK 67      /* the link has been severed            */  
  78. #define EADV    68      /* advertise error                      */  
  79. #define ESRMNT  69      /* srmount error                        */  
  80.   
  81. #define ECOMM   70      /* Communication error on send          */  
  82. #define EPROTO  71      /* Protocol error                       */  
  83.   
  84. /* Interprocess Robust Locks */  
  85. #define ELOCKUNMAPPED   72      /* locked lock was unmapped */  
  86.   
  87. #define ENOTACTIVE 73   /* Facility is not active               */  
  88. #define EMULTIHOP 74    /* multihop attempted                   */  
  89. #define EBADMSG 77      /* trying to read unreadable message    */  
  90. #define ENAMETOOLONG 78 /* path name is too long                */  
  91. #define EOVERFLOW 79    /* value too large to be stored in data type */  
  92. #define ENOTUNIQ 80     /* given log. name not unique           */  
  93. #define EBADFD  81      /* f.d. invalid for this operation      */  
  94. #define EREMCHG 82      /* Remote address changed               */  
  95.   
  96. /* shared library problems */  
  97. #define ELIBACC 83      /* Can't access a needed shared lib.    */  
  98. #define ELIBBAD 84      /* Accessing a corrupted shared lib.    */  
  99. #define ELIBSCN 85      /* .lib section in a.out corrupted.     */  
  100. #define ELIBMAX 86      /* Attempting to link in too many libs. */  
  101. #define ELIBEXEC 87     /* Attempting to exec a shared library. */  
  102. #define EILSEQ  88      /* Illegal byte sequence.               */  
  103. #define ENOSYS  89      /* Unsupported file system operation    */  
  104. #define ELOOP   90      /* Symbolic link loop                   */  
  105. #define ERESTART 91     /* Restartable system call              */  
  106. #define ESTRPIPE 92     /* if pipe/FIFO, don't sleep in stream head */  
  107. #define ENOTEMPTY 93    /* directory not empty                  */  
  108. #define EUSERS  94      /* Too many users (for UFS)             */  
  109.   
  110. /* BSD Networking Software */  
  111.         /* argument errors */  
  112. #define ENOTSOCK        95      /* Socket operation on non-socket */  
  113. #define EDESTADDRREQ    96      /* Destination address required */  
  114. #define EMSGSIZE        97      /* Message too long */  
  115. #define EPROTOTYPE      98      /* Protocol wrong type for socket */  
  116. #define ENOPROTOOPT     99      /* Protocol not available */  
  117. #define EPROTONOSUPPORT 120     /* Protocol not supported */  
  118. #define ESOCKTNOSUPPORT 121     /* Socket type not supported */  
  119. #define EOPNOTSUPP      122     /* Operation not supported on socket */  
  120. #define EPFNOSUPPORT    123     /* Protocol family not supported */  
  121. #define EAFNOSUPPORT    124     /* Address family not supported by */  
  122.                                 /* protocol family */  
  123. #define EADDRINUSE      125     /* Address already in use */  
  124. #define EADDRNOTAVAIL   126     /* Can't assign requested address */  
  125.         /* operational errors */  
  126. #define ENETDOWN        127     /* Network is down */  
  127. #define ENETUNREACH     128     /* Network is unreachable */  
  128. #define ENETRESET       129     /* Network dropped connection because */  
  129.                                 /* of reset */  
  130. #define ECONNABORTED    130     /* Software caused connection abort */  
  131. #define ECONNRESET      131     /* Connection reset by peer */  
  132. #define ENOBUFS         132     /* No buffer space available */  
  133. #define EISCONN         133     /* Socket is already connected */  
  134. #define ENOTCONN        134     /* Socket is not connected */  
  135. /* XENIX has 135 - 142 */  
  136. #define ESHUTDOWN       143     /* Can't send after socket shutdown */  
  137. #define ETOOMANYREFS    144     /* Too many references: can't splice */  
  138. #define ETIMEDOUT       145     /* Connection timed out */  
  139. #define ECONNREFUSED    146     /* Connection refused */  
  140. #define EHOSTDOWN       147     /* Host is down */  
  141. #define EHOSTUNREACH    148     /* No route to host */  
  142. #define EWOULDBLOCK     EAGAIN  
  143. #define EALREADY        149     /* operation already in progress */  
  144. #define EINPROGRESS     150     /* operation now in progress */  
  145.   
  146. /* SUN Network File System */  
  147. #define ESTALE          151     /* Stale NFS file handle */ 
10-22 17:01