消息队列,信号量,共享内存通称为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;
}
控制设置消息队列的接口