青岛市二手房:Linux进程间通信
来源:百度文库 编辑:九乡新闻网 时间:2024/05/13 16:10:53
消息队列就是消息的一个链表,它允许一个或多个进程向它写消息,一个或多个进程从中读消息。具有一定的FIFO的特性,但是可实现消息的随即查询。这些消息存在于内核中,由“队列ID”来标识。
消息队列的实现包括创建和打开队列、添加消息、读取消息和控制消息队列这四种操作。
msgget:创建和打开队列,其消息数量受系统限制。
msgsnd:添加消息,将消息添加到消息队列尾部。
msgrcv:读取消息,从消息队列中取走消息。
msgctl:控制消息队列。
int msgget (key_t key, int flag)
key:返回新的或已有队列的ID,IPC_PRIVATE
int msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int flag)
其中:msqid是消息队列的队列ID;
msgp是消息内容所在的缓冲区;
msgsz是消息的大小;
msgflg是标志,IPC_NOWAIT若消息并没有立即发送而调用进程会立即返回。
int msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz,long msgtyp, int flag)
msqid是消息队列的引用标识符;
msgp是接收到的消息将要存放的缓冲区;
msgsz是消息的大小;
msgtyp是期望接收的消息类型;
int msgctl (int msqid, int cmd, struct msqid_ds *buf)
msqid是消息队列的引用标识符;
cmd是执行命令;
buf是一个缓冲区。
cmd参数指定对于由msqid规定的队列要执行的命令:
IPC_STAT 取此队列的msqid_ds结构,并将其存放在buf指向的结构中。
IPC_SET 按由buf指向的结构中的值,设置与此队列相关的结构中的下列四个字段:
msg_perm.uid、msg_perm.gid、msg_perm;mode和msg_qbytes。此命令只能由下列两种进程执行:一种是其有效用户ID等于msg_perm.cuid或msg_perm.uid;另一种是具有超级用户特权的进程。只有超级用户才能增加msg_qbytes的值。
IPC_RMID 从系统中删除该消息队列以及仍在该队列上的所有数据。这种删除立即生效。仍在使用这一消息队列的其他进程在它们下一次试图对此队列进行操作时,将出错返回EIDRM。
此命令只能由下列两种进程执行:一种是其有效用户ID等于msg_perm.cuid或msg_perm.uid;另一种是具有超级用户特权的进程。
msgflg是标志。
具体看例子:
mesg_que_send.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
key_t key;
int msgkey;
pid_t pid;
int count=0;
struct msgbuf{
int mtype;
pid_t from;
int count;
char mtext[50];
}wmsg;
key=ftok("/home/yandongsheng/",10);
pid=getpid();//获得发送进程的id
if((msgkey=msgget(key,IPC_CREAT|0660))<0)
{
fprintf(stderr,"msgget error %s\n",strerror(errno));
exit(1);
}
printf("msgget key %d\n",msgkey);
fflush(stdout);
while(1)
{
count++;
bzero(&wmsg,sizeof(wmsg));
wmsg.mtype=10; //消息的类型
wmsg.count=count;
wmsg.from=pid;
strcpy(wmsg.mtext,"hello,i am coming");
if(msgsnd(msgkey,&wmsg,sizeof(wmsg.mtext),MSG_NOERROR)<0)
{
fprintf(stderr,"msgsnd error %s\n",strerror(errno));
}
sleep(2);
}
if((msgctl(msgkey,IPC_RMID,NULL))<0){
perror("msgctl");
exit(1);
}
return 0;
}
mesg_que_recv.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
key_t key;
pid_t pid;
int msgkey;
struct msgbuf{
int mtype;
pid_t from;
int count;
char mtext[50];
}rmsg;//消息的格式应该是一样的
pid=getpid();
key=ftok("/home/yandongsheng/",10);
while(1)
{
bzero(&rmsg,sizeof(rmsg));
if(msgrcv(msgkey,&rmsg,sizeof(rmsg.mtext),0,MSG_NOERROR)<0)
{
perror("msgrcv error");
}
printf("rmsg.from=%d\nmy pid is:",rmsg.from,pid);
printf("rmsg.mtype=%d\nrmsg.count=%d\nrmsg.mtext=%s\n",rmsg.mtype,rmsg.count,rmsg.mtext);
sleep(2);
}
if((msgctl(msgkey,IPC_RMID,NULL))<0){
perror("msgctl");
exit(1);
}
return 0;
}
先运行mesg_que_send.c 后运行mesg_que_recv.c 仅做演示
消息队列的实现包括创建和打开队列、添加消息、读取消息和控制消息队列这四种操作。
msgget:创建和打开队列,其消息数量受系统限制。
msgsnd:添加消息,将消息添加到消息队列尾部。
msgrcv:读取消息,从消息队列中取走消息。
msgctl:控制消息队列。
int msgget (key_t key, int flag)
key:返回新的或已有队列的ID,IPC_PRIVATE
int msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int flag)
其中:msqid是消息队列的队列ID;
msgp是消息内容所在的缓冲区;
msgsz是消息的大小;
msgflg是标志,IPC_NOWAIT若消息并没有立即发送而调用进程会立即返回。
int msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz,long msgtyp, int flag)
msqid是消息队列的引用标识符;
msgp是接收到的消息将要存放的缓冲区;
msgsz是消息的大小;
msgtyp是期望接收的消息类型;
int msgctl (int msqid, int cmd, struct msqid_ds *buf)
msqid是消息队列的引用标识符;
cmd是执行命令;
buf是一个缓冲区。
cmd参数指定对于由msqid规定的队列要执行的命令:
IPC_STAT 取此队列的msqid_ds结构,并将其存放在buf指向的结构中。
IPC_SET 按由buf指向的结构中的值,设置与此队列相关的结构中的下列四个字段:
msg_perm.uid、msg_perm.gid、msg_perm;mode和msg_qbytes。此命令只能由下列两种进程执行:一种是其有效用户ID等于msg_perm.cuid或msg_perm.uid;另一种是具有超级用户特权的进程。只有超级用户才能增加msg_qbytes的值。
IPC_RMID 从系统中删除该消息队列以及仍在该队列上的所有数据。这种删除立即生效。仍在使用这一消息队列的其他进程在它们下一次试图对此队列进行操作时,将出错返回EIDRM。
此命令只能由下列两种进程执行:一种是其有效用户ID等于msg_perm.cuid或msg_perm.uid;另一种是具有超级用户特权的进程。
msgflg是标志。
具体看例子:
mesg_que_send.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
key_t key;
int msgkey;
pid_t pid;
int count=0;
struct msgbuf{
int mtype;
pid_t from;
int count;
char mtext[50];
}wmsg;
key=ftok("/home/yandongsheng/",10);
pid=getpid();//获得发送进程的id
if((msgkey=msgget(key,IPC_CREAT|0660))<0)
{
fprintf(stderr,"msgget error %s\n",strerror(errno));
exit(1);
}
printf("msgget key %d\n",msgkey);
fflush(stdout);
while(1)
{
count++;
bzero(&wmsg,sizeof(wmsg));
wmsg.mtype=10; //消息的类型
wmsg.count=count;
wmsg.from=pid;
strcpy(wmsg.mtext,"hello,i am coming");
if(msgsnd(msgkey,&wmsg,sizeof(wmsg.mtext),MSG_NOERROR)<0)
{
fprintf(stderr,"msgsnd error %s\n",strerror(errno));
}
sleep(2);
}
if((msgctl(msgkey,IPC_RMID,NULL))<0){
perror("msgctl");
exit(1);
}
return 0;
}
mesg_que_recv.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
key_t key;
pid_t pid;
int msgkey;
struct msgbuf{
int mtype;
pid_t from;
int count;
char mtext[50];
}rmsg;//消息的格式应该是一样的
pid=getpid();
key=ftok("/home/yandongsheng/",10);
while(1)
{
bzero(&rmsg,sizeof(rmsg));
if(msgrcv(msgkey,&rmsg,sizeof(rmsg.mtext),0,MSG_NOERROR)<0)
{
perror("msgrcv error");
}
printf("rmsg.from=%d\nmy pid is:",rmsg.from,pid);
printf("rmsg.mtype=%d\nrmsg.count=%d\nrmsg.mtext=%s\n",rmsg.mtype,rmsg.count,rmsg.mtext);
sleep(2);
}
if((msgctl(msgkey,IPC_RMID,NULL))<0){
perror("msgctl");
exit(1);
}
return 0;
}
先运行mesg_que_send.c 后运行mesg_que_recv.c 仅做演示
Linux进程间通信
Linux环境进程间通信(一)
深刻理解Linux进程间通信(IPC)
Linux环境进程间通信(二): 信号(上)
linux进程通信有什么特点
Linux进程通信 共享内存+信号量
Linux下进程间通信:管道-pipe函数(转载转载)
Linux环境进程间通信(五): 共享内存(上)-Linux -华夏名网资讯中心 虚拟主机...
linux进程间通讯
windows进程间通信(转载)
利用SendMessage实现C#进程间通信
利用SendMessage实现C#进程间通信1
Linux下进程通信的八种方法[连载-记1]:所有方法登场
linux进程状态浅析
LINUX常见进程列表
Linux僵尸进程详解
Linux 核心--5.Linux进程 - fanqiang.com
PHP守护Linux/Unix进程
linux下socket通信概述,函数讲解
linux进程的休眠(等待队列)
linux 进程PV原语操作
linux进程学习总结——基本概念
linux创建新进程的过程
Linux启动及控制服务进程