1、进程间通信方式概述
进程间通信方式有:
管道(Pipo)和有名管道(FIFO):用于具有亲缘关系进行间通信,有名管道,允许无亲缘关系进程间的通信
信号(Signal):比较复杂的通信方式,用于通知接收进程有某种事件发生
消息队列:消息的连接表,包括Posix消息队列和System V消息队列
信号量(Signal)/信号灯:主要被用作进程间或同一进程不同线程之间的同步手段
共享内存:最有用的进程间通信方式,需要某种同步机制,互斥锁和信号量都可以
套接字:用于不同机器之间的进程间通信进程间通信的目的
数据传输、共享数据、通知事件、资源共享、进程控制
2、管道通信
特点:
半双工,数据只能一个方向流动,进行双方通信的时候要建立两个管道,用于父子间或兄弟进程间通信
一个进程向管道中写的数据内容被管道另一端的进程读出
写入的数据每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据
一般的I/O函数都可以用于管道,如close、read、write等读数据步骤:
若写端不存在,则认为以及读到了数据的末尾,读函数返回读出的字节数为0
若管道的写端存在,请求的字节数目大于PIPE_BUE(定义在include/linux/limits中),返回现有字节数,不大于的话,返回现有字节数或请求字节数
在管道写端关闭后,写入的数据将一直存在,直到被读出为止写端对读端的依赖性:
在向进程中写入数据时,至少应该存在某一个进程,其中管道读端没有被关闭。否则就会出现管道断裂,进程收到SIGPIPE信号,默认动作为进程终止
2.1 创建无名管道
函数详解
表头文件
#include <unistd.h>
定义函数
int pipe(int filedes[2]);
函数说明
用于建立管道
将文件描述符由参数filedes数组返回
filedes[0] 为管道的读取端
filedes[1] 为管道的写入端
返回值
成功返回零,否则返回-1
综合案例
#include <stdio.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
int filedes[2];
char buffer[80];
pipe(filedes);
if(fork() > 0)
{
char s[] = "hello!\n";
write(filedes[1],s,sizeof(s));
}
else
{
read(filedes[0],buffer,80);
printf("father %s",buffer);
}
return 0;
}
运行结果
linux@ubuntu:~/test$ gcc pipe_dome.c -o pipe_dome
linux@ubuntu:~/test$ ./pipe_dome
father hello!
2.2 创建有名管道
函数详解
表头文件
#include <sys/types.h>
#include <sys/stat.h>
定义函数
int mkfifo(const char* pathname,mode_t mode);
函数说明
pathname: 建立特殊的FIFO文件,该文件必须不存在
mode: 描述pahtname文件的权限
当使用open()打开文件时,O_NONBLOCK旗标会有下列影响:
当使用O_NONBLOCK旗标时,打开文件来读取操作会立刻返回;若没有其他进程打开文件来读取,则写入操作会返回ENXIO错误
没有使用O_NONBLOCK旗标时,打开FIFO文件读取操作会等到其他进程打开FIFO文件进行写入才能正常返回。同样,打开FIFO文件进行写入操作会等其他进程打开FIFO文件进程读取后才能正常返回
综合案例
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define FIFO "/home/linux/test/2"
int main(int argc,char *argv[])
{
char buffer[80];
int fd;
unlink(FIFO); //unlink删除指定的文件,若文件存在则删除它,确保后边mkfifo建立的特殊文件不存在
mkfifo(FIFO,0666);
if(fork() > 0)
{
char s[] = "hello!\n";
fd = open(FIFO,O_WRONLY);
write(fd,s,sizeof(s));
close(fd);
}
else
{
fd = open(FIFO,O_RDONLY);
read(fd,buffer,80);
printf("%s",buffer);
close(fd);
}
return 0;
}
运行结果
linux@ubuntu