ftok函数
key_t ftok( char * fname, int id )
//系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到。
参数:
fname就时你指定的文件名(该文件必须是存在而且可以访问的)。
id是子序号, 虽然为int,但是只有8个比特被使用(0‐255)。
返回值:
当成功执行的时候,一个key_t值将会被返回,否则 ‐1 被返回。
1、半双工
创建一个msg_write.c
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include<string.h>
struct msgbuf
{
long mtype;
char mtest[128];
char ID[4];
};
int main()
{
struct msgbuf sendbuf;
int msgid;
key_t key;
key = ftok("a.c",1);
msgid = msgget(key,IPC_CREAT|0755);
if(msgid == -1)
{
printf("creat message queue failed\n");
return -1;
}
system("ipcs -q");
printf("creat message queue succeed! msgid = %d\n",msgid);
//int msgbuf
sendbuf.mtype = 100;
while(1)
{
memset(sendbuf.mtest,0,128);
printf("please input to message queue:\n");
fgets(sendbuf.mtest,128,stdin);
msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.mtest),0);
}
return 0;
}
在创建一个msg_read.c
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include<string.h>
struct msgbuf
{
long mtype;
char mtest[128];
char ID[4];
};
int main()
{
struct msgbuf sendbuf,readbuf;
int msgid;
key_t key;
int readret;
key = ftok("a.c",1);
msgid = msgget(key,IPC_CREAT|0755);
if(msgid == -1)
{
printf("creat message queue failed\n");
return -1;
}
system("ipcs -q");
printf("creat message queue succeed! msgid = %d\n",msgid);
//int msgbuf
sendbuf.mtype = 100;
while(1)
{
memset(readbuf.mtest,0,128);
readret = msgrcv(msgid,(void *)&readbuf,128,100,0);
printf("message is:%s\n",readbuf.mtest);
printf("total is %d byte\n",readret);
}
return 0;
}


可以实现进程间通信,但这个是半双工的,只能write写read读
2、全双工
创建两个文件,msg_service.c
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include<string.h>
#include <unistd.h>
struct msgbuf
{
long mtype;
char mtest[128];
char ID[4];
};
int main()
{
struct msgbuf sendbuf,readbuf;
int msgid;
key_t key;
pid_t pid;
key = ftok("a.c",1);
msgid = msgget(key,IPC_CREAT|0755);
if(msgid == -1)
{
printf("creat message queue failed\n");
return -1;
}
system("ipcs -q");
printf("creat message queue succeed! msgid = %d\n",msgid);
//int msgbuf
sendbuf.mtype = 100;
pid = fork();
//parent process write 100
if(pid>0)
{
while(1)
{
memset(sendbuf.mtest,0,128);
printf("please input to message queue:\n");
fgets(sendbuf.mtest,128,stdin);
msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.mtest),0);
}
}
//child process read 200
if(pid==0)
{
while(1)
{
memset(readbuf.mtest,0,128);
msgrcv(msgid,(void *)&readbuf,128,200,0);
printf("receive byte from message queue is:%s\n",readbuf.mtest);
}
}
return 0;
}
核心结构
- 用
ftok("a.c",1)拿钥匙、msgget建同一个消息队列 fork()拆分两个进程:- 父进程:负责发 100 类型消息
- 子进程:负责收 200 类型消息
创建msg_client.c
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include<string.h>
#include <unistd.h>
struct msgbuf
{
long mtype;
char mtest[128];
char ID[4];
};
int main()
{
struct msgbuf sendbuf,readbuf;
int msgid;
key_t key;
pid_t pid;
key = ftok("a.c",1);
msgid = msgget(key,IPC_CREAT|0755);
if(msgid == -1)
{
printf("creat message queue failed\n");
return -1;
}
system("ipcs -q");
printf("creat message queue succeed! msgid = %d\n",msgid);
//int msgbuf
sendbuf.mtype = 200;
pid = fork();
//child process write 200
if(pid==0)
{
while(1)
{
memset(sendbuf.mtest,0,128);
printf("please input to message queue:\n");
fgets(sendbuf.mtest,128,stdin);
msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.mtest),0);
}
}
//parent process read 100
if(pid>0)
{
while(1)
{
memset(readbuf.mtest,0,128);
msgrcv(msgid,(void *)&readbuf,128,100,0);
printf("receive byte from message queue is:%s\n",readbuf.mtest);
}
}
return 0;
}
- 子进程:负责发 200 类型消息
- 父进程:负责收 100 类型消息

成功实现,值得注意的是,一定要提前创建a.c文件,不然就会一直读取空消息,疯狂刷屏