一、管道
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;
}