System VIPC机制主要由消息队列、信号量和共享内存3种机制。
使用ipcs命令可以查看当前系统正在使用的IPC;
创建IPC结构,需指定一个关键字(key),关键字的数据类型由系统规定key_t,通常在头文件<sys/types.h>中被规定为长整型。
Linux--System VIPC基础
Linux--System VIPC基础

一、消息队列

消息队列是消息的链接表,存放在内核中,并由消息队列标识符标识。
消息队列需要两种类型的数据结构:
1)msqid_ds:标识整个消息队列的基本情况,包括队列的权限、拥有者和操作权限等,还有两个指针,分别指向队列的第一个消息和最后一个消息。
2)msg:整个队列的主体,一个队列有若干消息,每个msg结构基本属性包括消息类型、消息大小、消息内容指针和下一个msg的位置。
Linux--System VIPC基础
Linux--System VIPC基础

msg的结构体如下:

struct msg_msg{
     struct list_head m_list;
     long m_type;
     int m_ts;
     struct msg_msgseg *next;
     void *security;
}   

用msgget创建或打开消息队列:
头文件:<sys/msg.h>
int msgget(key_t key ,int flag)
key为IPC的可能取值
flag的低位用来确定消息队列的访问权限,如0666=rw-rw-rw
Linux--System VIPC基础
Linux--System VIPC基础
用msgctl对消息队列属性进行控制
头文件:<sys/msg.h>
int msgctl(int msqid,int cmd,struct msqid_ds *buf);
若成功则为0,出错则为-1
Linux--System VIPC基础
Linux--System VIPC基础
Linux--System VIPC基础
Linux--System VIPC基础
Linux--System VIPC基础
下面为两段代码
receive为接收端,接收send发来的消息
send为发送端,向receive发送消息
编译时需要启动两个终端同时编译

/*receive.c */  
#include <stdio.h>   
#include <sys/types.h>   
#include <sys/ipc.h>   
#include <sys/msg.h>   
#include <errno.h>   
  
#define MSGKEY 1024   
  
struct msgstru  
{  
   long msgtype;  
   char msgtext[2048];  
};  
  
/*子进程,监听消息队列*/  
void childproc(int type){  
  struct msgstru msgs;  
  int msgid,ret_value;  
  char str[512];  
    
  while(1){  
     msgid = msgget(MSGKEY,IPC_EXCL );/*检查消息队列是否存在 */  
     if(msgid < 0){  
        printf(".\n");//msq not existed! errno=%d [%s]\n",errno,(char *)strerror(errno));  
        sleep(2);  
        continue;  //continue  break 两者区别
     }  
     /*接收消息队列*/  
     ret_value = msgrcv(msgid,&msgs,sizeof(struct msgstru),type,0);  
     printf("text=[%s] pid=[%d]\n",msgs.msgtext,getpid());  
  }  
  return;  
}  
  
void main()  
{  
  int i,cpid;  
  
  /* create 2 child process */  
  for (i=1;i<=2;i++)
    {  
     cpid = fork();  
     if (cpid < 0)  
        printf("fork failed\n");  
     else if (cpid ==0) /*child process*/  
         {
                 printf("pid=%d,type=%d",getpid(),i);
        childproc(i);  
         }
  }  
}
/*send.c*/                                                                        
#include <stdio.h>                                                                
#include <sys/types.h>                                                            
#include <sys/ipc.h>                                                              
#include <sys/msg.h>                                                              
#include <errno.h>                                                                
#include <stdlib.h>

//IPC可能取值                                                                             
#define MSGKEY 1024                                                               
                                                                                  
struct msgstru                                                                    
{                                                                                 
   long msgtype;                                                                  
   char msgtext[2048];                                                            
};                                                                                
                                                                                  
main()                                                                            
{                                                                                 
  struct msgstru msgs;                                                            
  int msg_type;                                                                   
  char str[256];                                                                  
  int ret_value;                                                                  
  int msqid;                                                                      
                                                                                  
  msqid=msgget(MSGKEY,IPC_EXCL);  /*检查消息队列是否存在*/                        
  if(msqid < 0){                                                                  
    msqid = msgget(MSGKEY,IPC_CREAT|0666);/*创建消息队列*/                        
    if(msqid <0){                                                                 
    printf("failed to create msq | errno=%d [%s]\n",errno,(char *)strerror(errno));       
    exit(-1);                                                                     
    }                                                                             
  }                                                                               
                                                                                  
  while (1){                                                                      
    printf("input message type(end:0):");                                         
    scanf("%d",&msg_type);                                                        
    if (msg_type == 0)                                                            
       break;                                                                     
    printf("input message to be sent:");                                          
    scanf ("%s",str);                                                             
    msgs.msgtype = msg_type;

	//strcpy拷贝函数
    strcpy(msgs.msgtext, str);                                                    
    /* 发送消息队列 */                                                            
    ret_value = msgsnd(msqid,&msgs,sizeof(struct msgstru),IPC_NOWAIT);            
    if ( ret_value < 0 ) {                                                        
       printf("msgsnd() write msg failed,errno=%d[%s]\n",errno,(char *)strerror(errno));  
       exit(-1);                                                                  
    }                                                                             
  }                                                                               
  msgctl(msqid,IPC_RMID,0); //删除消息队列                                        
}

相关文章:

  • 2021-07-30
  • 2022-12-23
  • 2021-11-30
  • 2022-01-02
猜你喜欢
  • 2021-12-27
  • 2021-12-08
  • 2022-12-23
  • 2021-07-25
  • 2021-12-23
  • 2021-04-10
  • 2022-02-02
相关资源
相似解决方案