1消息队列

消息队列是一个消息链表,允许一个或多个进程向它写消息,另外的进程从中读取消息,具有FIFO的特性,但是可实现随即访问。在内核中,消息队列由"队列id"标识。

 

2.使用过程

创建消息队列==>添加消息==>读取消息==>删除队列

<1>创建消息队列 msgget()

 

  int msgget(key_t key,int flag);

参数:key  为IPC_PRIVATE时,建立新的消息队列

           不为IPC_PRIVATE,根据flag是否有IPC_CREAT确定

      flag 标志位

返回:成功,返回消息队列识别代码msgid  失败 返回-1 错误信息存放在errno中

<2>向消息队列添加消息

 

  int msgsnd(int msgid,struct msgbuf *msgp,size_t msgsz,int flag);

参数:msgid  消息队列id 由msgget()得到

      msgp  存放消息类型和内容

  1. struct msgbuf{ 
  2.  long mtype;/*消息类型*/ 
  3.   char mtext[1];/*消息内容*/ 
  4.  } 

msgbuf在头文件中未实际定义,需要自己定义。

       msgsz 消息大小

       flag 为IPC_NOWAIT时,未立即发送,调用进程立即返回

返回:成功,返回消息队列识别代码  失败 返回-1 错误信息存放在errno中

<3>从消息队列读取消息

  int msgrcv(int msgid,struct msgbuf *msgp,size_t msgsz,long msgty,int flag);

参数: msgid  消息队列id 由msgget()得到

      msgp  存放消息类型和内容

      msgsz 消息大小

      msgty 消息类型

      flag 为IPC_NOWAIT时,未立即发送,调用进程立即返回

返回:成功,返回消息队列识别代码  失败 返回-1 错误信息存放在errno中

 

<4>控制消息队列

  int msgctl(int msgid,int cmd,struct msgid_ds, *buf);

参数: msgid  消息队列id 由msgget()得到

      cmd  IPC_STAT   将消息队列信息写入buf

           IPC_SET    根据buf设置为消息队列

           IPC_RMID   删除消息队列

返回:成功,返回消息队列识别代码  失败 返回-1 错误信息存放在errno中

举例:

1. 子进程向消息队列发送消息,由父进程读出

  1. #include<sys/ipc.h> 
  2. #include<sys/msg.h> 
  3. #include<sys/types.h> 
  4. #include<sys/stat.h> 
  5. #include<unistd.h> 
  6. #include<stdio.h> 
  7. #include<string.h> 
  8.  
  9.  
  10. #define KEY 1234 
  11. #define MSGTYPE 4321 
  12. #define SIZE 512 
  13.  
  14. int main() 
  15.    int msgid;/*消息队列id*/ 
  16.    pid_t pid; 
  17.    struct message  
  18.   { 
  19.    long mtype; 
  20.    char mtext[SIZE]; 
  21.   }msg; 
  22.    
  23.     msgid=msgget(KEY,IPC_CREAT); 
  24.  
  25.    pid=fork(); 
  26.    if(pid<0) 
  27.     { 
  28.      perror("fork error!\n"); 
  29.      exit(0); 
  30.     } 
  31.    if(pid==0) 
  32.   { 
  33.     /*子进程发送消息*/ 
  34.     msg.mtype=MSGTYPE;/*设置消息类型*/ 
  35.     sprintf(msg.mtext,"hello linux!");/*设置消息内容*/ 
  36.     msgsnd(msgid,&msg,SIZE,IPC_NOWAIT);/*发送消息*/ 
  37.     printf("son proc send msg!\n"); 
  38.    exit(0); 
  39.   } 
  40. /*父进程接收消息*/ 
  41.    sleep(2); 
  42.   msgrcv(msgid,&msg,SIZE,MSGTYPE,MSG_NOERROR|IPC_NOWAIT);/*接收消息*/ 
  43.   printf("parent get message:%s\n",msg.mtext,IPC_NOWAIT); 
  44.   msgctl(msgid,IPC_RMID,NULL);/*删除消息队列*/