进程的五种通信方式

一、管道

1、什么是管道

我们把一个进程连接到另一个进程的数据流称为一个管道。它是最古老的进程通信形式。

2、原型(匿名管道):

#include <unistd.h>
功能:创建⼀⽆名管道
原型
int pipe(int fd[2]);
参数
fd:⽂件描述符数组,其中fd[0]表⽰读端, fd[1]表⽰写端
返回值:成功返回0,失败返回错误代码

3.管道的特点

 (1).只能用于拥有共同祖先的进程进行通信,通常一个进程先创建管道,然后该进程调用fork,然后父子进程便可以一同应用此管道。

(2).管道提供流式服务。

(3).一般而言,进程退出管道释放,管道的生命周期随进程。

(4).一般而言,内核会对管道操作进行同步与互斥。

(5).管道是半双工,数据只能向一个方向流动,如果要实现双方通信时,则需要建立两个管道。

二、命名管道

1.建立原因:管道本只能在拥有共同祖先的进程之间通信,若想在无关进程之间通信,那么则使用FIFO文件来实现,被称为命名管道。

2.创建命名管道

(1)命名管道可以从命令行创建

$ mkfifo filename

(2).命名管道也可以在程序中创建

int mkfifo(const char* filename, mode_t mode);

(3)创建命名管道

int main(int argc, char *argv[])
{
 mkfifo("p2", 0644);
 return 0;
}

3.匿名管道与命名管道的区别:

  • 匿名管道由pipe创建并打开
  • 命名管道由mkfifo创建,由open打开
  • 两者唯一的区别就是创建和打开的方式不同,一旦这些完成之后,他们具有相同的语义

三、消息队列

1、概念

  • 消息队列提供了从一个进程向另一个进程发送一块数据的方法。
  • 每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型。
  • 消息队列的不足是消息队列有最大长度的限制(MSGMAX),并且还有字节数的限制(MSGMNB),消息队列的总数也有限制(MSGMNI)。

2.原型:

(1).msgget()函数

功能:⽤来创建和访问⼀个消息队列
原型
 int msgget(key_t key, int msgflg);
参数
 key: 某个消息队列的名字
 msgflg:由九个权限标志构成,它们的⽤法和创建⽂件时使⽤的mode模式标志是⼀样的
返回值:成功返回⼀个⾮负整数,即该消息队列的标识码;失败返回-1

(2)msgctl()函数

功能:消息队列的控制函数
原型
 int msgctl(int msqid, int cmd, struct msqid_ds *buf);
参数
 msqid: 由msgget函数返回的消息队列标识码
 cmd:是将要采取的动作,(有三个可取值)
返回值:成功返回0,失败返回-1

(3)msgsnd()函数

功能:把⼀条消息添加到消息队列中
原型
 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数
 msgid: 由msgget函数返回的消息队列标识码
 msgp:是⼀个指针,指针指向准备发送的消息,
 msgsz:是msgp指向的消息⻓度,这个⻓度不含保存消息类型的那个long int⻓整型
 msgflg:控制着当前消息队列满或到达系统上限时将要发⽣的事情
 msgflg=IPC_NOWAIT表⽰队列满不等待,返回EAGAIN错误。
返回值:成功返回0;失败返回-1

(4).msgrcv()函数

功能:是从⼀个消息队列接收消息
原型
 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
参数
 msgid: 由msgget函数返回的消息队列标识码
 msgp:是⼀个指针,指针指向准备接收的消息,
 msgsz:是msgp指向的消息⻓度,这个⻓度不含保存消息类型的那个long int⻓整型
 msgtype:它可以实现接收优先级的简单形式
 msgflg:控制着队列中没有相应类型的消息可供接收时将要发⽣的事
返回值:成功返回实际放到接收缓冲区⾥去的字符个数,失败返回-1

四、共享内存

(1).shmget函数

功能:⽤来创建共享内存
原型
 int shmget(key_t key, size_t size, int shmflg);
参数
 key:这个共享内存段名字
 size:共享内存⼤⼩
 shmflg:由九个权限标志构成,它们的⽤法和创建⽂件时使⽤的mode模式标志是⼀样的
返回值:成功返回⼀个⾮负整数,即该共享内存段的标识码;失败返回-1

(2).shmat函数

功能:将共享内存段连接到进程地址空间
原型
 void *shmat(int shmid, const void *shmaddr, int shmflg);
参数
 shmid: 共享内存标识
 shmaddr:指定连接的地址
 shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回⼀个指针,指向共享内存第⼀个节;失败返回-1

(3).shmdt函数

功能:将共享内存段与当前进程脱离
原型
 int shmdt(const void *shmaddr);
参数
 shmaddr: 由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段

(4).shmctl函数

功能:⽤于控制共享内存
原型
 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
 shmid:由shmget返回的共享内存标识码
 cmd:将要采取的动作(有三个可取值)
 buf:指向⼀个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1

五、信号量

信号量本质上是一个计数器

信号量结构体伪代码:

struct semaphore
{
 int value;
 pointer_PCB queue;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值