unix/linux进程间的通信方式有:管道(无名管道,命名管道),消息队列,共享内存,信号,信号量,套接字。本文主要探讨管道通信的方式。
管道的特点
1.半双工,单方向流动,双方通信时,需建立两个管道;
2.用于父子进程或者兄弟进程之间
3.单独构成文件系统,管道对于两端的进程而言,是一个文件,但不是 一个普通的文
件,不属于某个文件系统,单独构成一种文件系统,并且只存在内存中;
4.数据的读写,一个进程写,另一个进程读出,写入的内容在管道末尾,从管道的头
部读取数据;
管道的使用场景
数据传输:进程间的数据发送,大小为一字节到几兆。
共享数据:多共享数据,某一进程对共享数据的修改,其他进程实时接受。
通知事件:进程向一个或多个进程发送消息(如进程终止时要通知父进程)。
资源共享:多进程共享资源,内核提供锁和同步机制。
进程控制:进程完全控制另一进程,实时知道它的状态改变,拦截异常(Dbug)。
管道的分类
无名管道
int pipe(int pipefd[2]);
参数
fd[0]:读取管道内容
fd[1]:写入管道内容
返回值
执行成功返回0,失败返回-1
命名管道
int mkfifo(const char *pathname, mode_t mode);
参数
pathname:文件路径
mode:权限(读4,写2,执行1)
返回值
执行成功返回0,失败返回-1
demo1:
1.创建父子进程
2.子进程写入hello到管道
3.父进程读取管道内容
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void result()
{
int p_ret;
int fd[2];
int pid;
char *buf = "hello";
char *read_buf;
read_buf = (char *)malloc(strlen(buf));
p_ret = pipe(fd);
if(p_ret == -1)
{
printf("pipe create fail\n");
perror("why");
exit(-1);
}
pid = fork();
if(pid == 0)
{
close(fd[0]);
write(fd[1],buf,strlen(buf));
exit(-1);
}
else if(pid > 0)
{
close(fd[1]);
read(fd[0],read_buf,strlen(buf));
printf("pipe contex : %s\n",read_buf);
wait();
}
else
{
printf("fork create fail\n");
perror("why");
exit(-1);
}
}
int main()
{
result();
return 0;
}
结果示例:
demo2:
1.一终端建立有名管道,并写入hello
2.另一终端读取管道文件内容
write:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
void result()
{
int fd;
char *buf = "hello";
fd = open("./file",O_WRONLY);
if(fd == -1)
{
printf("create pipe fail\n");
perror("why");
exit(-1);
}
write(fd,buf,strlen(buf));
close(fd);
}
int main()
{
result();
return 0;
}
read:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
void result()
{
int fd;
char *buf;
buf = (char *)malloc(10);
fd = open("./file",O_RDONLY);
if(fd == -1)
{
printf("open pipe fail\n");
perror("why");
exit(-1);
}
read(fd,buf,10);
printf("pipe context : %s\n",buf);
close(fd);
}
int main()
{
result();
return 0;
}
结果示例: