linux 环境下的进程间的通信方式主要有:管道,有名和无名管道, 这种方式适用于具有亲缘关系的进程之间的通信;
信号:
消息队列:
共享内存:
信号量:
套接字:
这次主要涉及消息队列:
1. 需要用到的函数:
1)得到消息队列的描述子
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
使用方法:pathname,一般是一个带路径的文件的名字,常取做 “.”
proj_id 这个是有自己设定的。
通过这两个参数确定一个key值,然后用于msgget函数:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
使用方法:key 来自上面的函数, msgflg 通常的用法与read中的相似,一个进程中:在创建的时候,我们使用IPC_CREAT, 另一个进程:在使用的时候一般采用msgflg的值为0;
2)消息的格式:
struct msbuf 一般具有两个部分,一个部分是 msgtype, 另一个是msgname消息队列的内容,我们一般采用消息队列传输具有一定结构类型的数据;现在假设需要传送的结构为:
typedef struct _S{
int a;
int b;
int c;
}TS;
下面是我们的消息结构:
struct msbuf{
long msg_type;
TS msg_name;
}
3)发送消息和接收消息:
#include <sys/types.h>
key =ftok( ".", 3);
ts.a = 11;
ts.b = 12;
student.msg_type = 1;
student.msg_name = ts;
if(key < 0)
{
perror( "It is a wrong key\n");
}
msgid =msgget(key,IPC_CREAT);
send =msgsnd(msgid, &student, sizeof(ts), 0);
if(send < 0)
{
perror( "write wrong!\n");
}
return 0;
}
typedef struct _S{
int a;
int b;
}TS;
struct msbuf
{
long msg_type;
TS msg_name;
};
int main()
{
struct msbuf rc;
key_t key;
int msgid;
int recive;
key =ftok( ".", 3);
if(key < 0)
{
perror( "It is a wrong key\n");
}
msgid =msgget(key, 0);
printf( "start rece \n");
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
使用方法:① int msqid 这是通过上面的两个函数得到的。
②const void *msgop; 只需要在此处填入自己构造的消息的指针即可。此处使用 msbuf *;
③size_t msgsz 这个指的是消息的大小,这个不包括long type,我们在此处使用sizeof(TS);
④ int msgflg 可以为以下:IPC_CREAT、IPC_EXCL、IPC_NOWAIT或三者的或结果。
⑤ long msgtyp, 指明要结构的消息的类型;
范例程序:
// this is ipc write !
# include <stdio.h >
# include <errno.h >
# include <sys /types.h >
# include <sys /ipc.h >
# include <sys /msg.h >
# define BUFLENGTH 10
typedef struct _S{
int a;
int b;
}TS;
struct msbuf
{
long msg_type;
TS msg_name;
};
int main()
{
struct msbuf student;
TS ts;
key_t key;
int msgid;
int send;
# include <stdio.h >
# include <errno.h >
# include <sys /types.h >
# include <sys /ipc.h >
# include <sys /msg.h >
# define BUFLENGTH 10
typedef struct _S{
int a;
int b;
}TS;
struct msbuf
{
long msg_type;
TS msg_name;
};
int main()
{
struct msbuf student;
TS ts;
key_t key;
int msgid;
int send;
key =ftok( ".", 3);
ts.a = 11;
ts.b = 12;
student.msg_type = 1;
student.msg_name = ts;
if(key < 0)
{
perror( "It is a wrong key\n");
}
msgid =msgget(key,IPC_CREAT);
send =msgsnd(msgid, &student, sizeof(ts), 0);
if(send < 0)
{
perror( "write wrong!\n");
}
return 0;
}
// this is ipc read!
# include <stdio.h >
# include <errno.h >
# include <sys /types.h >
# include <sys /ipc.h >
# include <sys /msg.h >
# define BUFLENGTH 10
# include <stdio.h >
# include <errno.h >
# include <sys /types.h >
# include <sys /ipc.h >
# include <sys /msg.h >
# define BUFLENGTH 10
typedef struct _S{
int a;
int b;
}TS;
struct msbuf
{
long msg_type;
TS msg_name;
};
int main()
{
struct msbuf rc;
key_t key;
int msgid;
int recive;
key =ftok( ".", 3);
if(key < 0)
{
perror( "It is a wrong key\n");
}
msgid =msgget(key, 0);
printf( "start rece \n");
recive
=msgrcv(msgid,
&rc,
sizeof(TS),
1,
0);
if(recive < 0)
{
perror( "read wrong!\n");
}
else
{
printf( "rece \n");
printf( "read is :%d\n",rc.msg_name.a);
printf( "read is :%d\n",rc.msg_name.b);
}
return 0;
}
if(recive < 0)
{
perror( "read wrong!\n");
}
else
{
printf( "rece \n");
printf( "read is :%d\n",rc.msg_name.a);
printf( "read is :%d\n",rc.msg_name.b);
}
return 0;
}