进程间的通讯IPC:管道,信号量,共享内存,消息队列,套接字
管道(有名管道和无名管道)(有名无名区别)
有名管道
有名管道可以在任意两个进程之间通信
有名管道的创建:
◼ 命令创建: mkfifo FIFO
◼ 系统调用创建
打开管道在内存中分配空间
写端关闭读端read()返回为零0
读端关闭写入数据就会产生异常(收到信号SIGPICE)
管道的通讯方式是属于半双工(收音机属于半工,打电话属于全双工)
无名管道
无名管道主要应用于父子进程间的通信。
pipe()成功返回 0,失败返回-1
fds[0]是管道读端的描述符
fds[1]是管道写端的描述符
代码演示
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
int main()
{
int fd[2];//fd[0]读 fd[1]写
if( pipe(fd) == -1)//pipe创建无名管道
{
printf("create pipe err\n");
exit(0);
}
//创建子进程
pid_t pid=fork();
if( pid == -1 )
{
close(fd[0]);
close(fd[1]);
exit(0);
}
if( pid == 0 )
{
//读
close(fd[1]);
char buff[128]={0};
read(fd[0],buff,127);
printf("child:%s\n",buff);
close(fd[0]);
}
else
{
//写
close(fd[0]);
write(fd[1],"hello",5);
close(fd[1]);
}
exit(0);
}
3 管道的特点
◼ 无论有名还是无名,写入管道的数据都在内存中
◼ 管道是一种半双工通信方式(通信方式有单工、半双工、全双工)
◼ 有名和无名管道的区别:有名可以在任意进程间使用,而无名主要在父子进程间
2、信号量
临界资源:同一时刻,只允许被一个进程或线程访问的资源
临界区:访问临界资源的代码段
ipcs -s 查看信号量
ipcrm -s semid 删除信号量
3.共享内存
共享内存为多个进程之间共享和传递数据提供了一种有效的方式。共享内存是先在物理
内存上申请一块空间,多个进程可以将其映射到自己的虚拟地址空间中。所有进程都可以访
问共享内存中的地址,就好像它们是由 malloc 分配的一样。如果某个进程向共享内存写入了
数据,所做的改动将立刻被可以访问同一段共享内存的任何其他进程看到。由于它并未提供
同步机制,所以我们通常需要用其他的机制来同步对共享内存的访问