消息队列,信号量,共享内存通称为system-V IPC,在系统中他们都是用一种名为key的键值来做唯一标识,他们被创建后,不会因为进程的退出而消失,而会持续的存在,除非调用特殊的函数或命令删除。
ftok函数
1)pathname:在一个项目里面,所有进程都在同一路径里面,pathname指的是一个路径。
2)proj_id:IPC的标识,表示key值
当路径和IPC的标识都一样时,创建出来的key值是一样的。
key的作用:申请对应传输机制的空间资源和确定传输机制
消息队列:消息队列需要的空间,确定传输机制
共享内存:共享内存需要的空间,确定传输机制
信号量:信号量需要的空间,确定传输机制
注意:当要重复创建不同的但是有相同的IPC时,需要不同的key值
不一样的key值,就可以创建多个相同的IPC
当key值相同,操作的就是同一个IPC对象
例子:创建两个不同的key值:
#define IPC_MASK_A 1 #define IPC_MASK_B 2 int main() { key_t key_a = ftok("./",IPC_MASK_A); key_t key_b = ftok("./",IPC_MASK_B); if(key_a == -1 || key_b == -1) { perror("ftok"); return -1; } else { printf("%d---%d\n",key_a,key_b); } return 0; }
如何用key值创建消息队列-----msgget
mode:访问的权限只有读和写没有执行(0666)
查看和删除当前系统的IPC对象
示例代码:
#include <stdio.h> #include <errno.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define IPC_MASK_A 1 #define IPC_MASK_B 2 int main() { key_t key_a = ftok("./",IPC_MASK_A); key_t key_b = ftok("./",IPC_MASK_B); if(key_a == -1 || key_b == -1) { perror("ftok"); return -1; } else { printf("%d---%d\n",key_a,key_b); } int msg_queue_id_a = msgget(key_a,IPC_CREAT | 0666); int msg_queue_id_b = msgget(key_b,IPC_CREAT | 0666); if(msg_queue_id_a == -1 || msg_queue_id_b == -1) { perror("msgget"); return -1; } else { printf("%d---%d\n",msg_queue_id_a,msg_queue_id_b); } return 0; }
消息队列如何通信
示例代码:
#include <stdio.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MSG_LENGTH 24 #define IPC_MASK_A 1 #define IPC_MASK_B 2 #define MSG_MASK 1L int main() { key_t key_a = ftok("./",IPC_MASK_A); key_t key_b = ftok("./",IPC_MASK_B); if(key_a == -1 || key_b == -1) { perror("ftok"); return -1; } else { printf("%d---%d\n",key_a,key_b); } int msg_queue_id_a = msgget(key_a,IPC_CREAT | 0666); int msg_queue_id_b = msgget(key_b,IPC_CREAT | 0666); if(msg_queue_id_a == -1 || msg_queue_id_b == -1) { perror("msgget"); return -1; } else { printf("%d---%d\n",msg_queue_id_a,msg_queue_id_b); } struct msgbuf { long mtype; /* message type, must be > 0 */ char mtext[MSG_LENGTH]; /* message data */ }msg_inf_send,msg_inf_rev; /*调用msgsnd函数发送消息*/ memset(&msg_inf_send,0,sizeof(msg_inf_send)); memset(&msg_inf_rev,0,sizeof(msg_inf_rev)); msg_inf_send.mtype = MSG_MASK; memset(msg_inf_send.mtext,0,MSG_LENGTH); memset(msg_inf_rev.mtext,0,MSG_LENGTH); printf("请输入要发送的消息:"); scanf("%s",msg_inf_send.mtext); int msgsnd_ret = msgsnd(msg_queue_id_a,&msg_inf_send,strlen(msg_inf_send.mtext),0); if(msgsnd_ret == -1) { perror("msgsnd"); return -1; } else { printf("发送消息成功!!!!\n"); } /*调用msgrcv读取消息*/ int msgrcv_ret = msgrcv(msg_queue_id_a,&msg_inf_rev,MSG_LENGTH,MSG_MASK,0); if(msgrcv_ret == -1) { perror("msgrcv"); return -1; } else { printf("消息是:%s\n",msg_inf_rev.mtext); } int msgctl_ret_a = msgctl(msg_queue_id_a,IPC_RMID,NULL); int msgctl_ret_b = msgctl(msg_queue_id_b,IPC_RMID,NULL); if(msgctl_ret_a == -1 || msgctl_ret_b == -1) { perror("msgctl"); return -1; } return 0; }
控制设置消息队列的接口