Linux进程间通信--消息队列

基本概念

  • 消息队列就是由操作系统维护的消息链表,存放于内核中并由消息队列标识符标识,有足够权限的进程可以向队列中添加消息,被赋予读权限的进程可以读取队列中的消息,消息队列的生命周期不随进程随内核。

消息队列与管道的比较

  • 相同点: 管道和消息队列都是进程间通信的方式。
  • 不同点:
  • 1.管道只能承载无格式字节流,而消息队列可以指定消息的类型。
  • 2.管道的生命周期随进程,而消息队列的生命周期随内核。

消息队列有关函数

  • key_t ftok(const char *pathname, int proj_id);//用某种方法获取key,第一个参数,和第二个参数都是自己随便给,(第一个参数必须是已存在且可以访问的文件名),只要不和系统重复就行。

  • int msgget(key_t key, int msgflg);//迎来创建或者访问一个消息队列。第二个参数有l两个选项,IPC_CREAT、IPC_EXCL。如果同时设置两个,表示如果创建的队列已经存在,返回错(-1),如果不存在,创建并返回非负整数,表示该队列的标识符。如果只设置IPC_CREAT,表示如果创建的已经存在,返回该队列的标识符,如果不存在,返回-1.如果新创建的不加权限,默认为0,在创建时也可以加上|权限(|0644),表示该消息队列的权限。 其实就是设置两个用来创建新的消息队列,设置一个用来访问已经存在的消息队列。

  • int msgctl(int msqid, int cmd, struct msqid_ds *buf);//用来控制消息队列,第一个参数为队列标识符,第二个有三个选项,只了解一个IPC_RMID,用来销毁队列,第三首个参数为NULL。返回值为-1表示销毁失败

  • int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);//用来向消息队列发送消息,第二个参数是指向消息结构体的指针,第三个参数是消息结构体数组成员的大小,最后一个参数为0,表示阻塞式等待;返回值为-1表示发送失败。

  • ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);//这里的倒数第二个参数是接收的类型,这是由发送方决定。返回值为-1表示接受失败

实现消息队列,代码如下:

  • comm.h
    这里写图片描述
  • comm.c
    这里写图片描述

这里写图片描述
- server.c(创建队列,先接收消息,再发送) client.c(访问队列,先发送消息,再接收消息)
这里写图片描述
- Makefile
这里写图片描述

消息队列实现进程间通信的原理

  • 无论进程间通信的方式是什么,本质就是让不同的进程想办法”看到“一份公共资源,在上面的代码中,两个进程通过相同的方法ftok()获取相同的键值k,这样再通过msgget()传入相同的键值k获得相同的msgid(消息队列描述符),这样两个进程就可以”看到“一份公共的资源,这个临界资源就是migid所表示的消息队列,通过这个消息队列,两个进程就实现了通信的目的。

猜你喜欢

转载自blog.csdn.net/virgofarm/article/details/80383916