目录
为什么需要进程间通信?
- 数据传输:一个进程需要将它的数据发送给另一个进程
- 资源共享:多个进程之间共享相同的资源。
- 事件通知:一个进程需要向另一个或一组进程发送消息,通知它们发送了某种事件。
- 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程)此时控制进程希望能够拦截另一个进程所有操作,并能及时知道它的状态改变
Linux进程间通信(IPC)由下面及部分发展而来:
- UNIX进程间通信
- 基于System V进程间通信
- POSIX进程间通信
什么是管道?
管道是单向的、先进先出的,它把一个进程的输出和另一个进程的输入连接在一起。
一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)从管道的头部读出数据。
管道包括无名管道和有名管道两种:
无名管道用于父进程和子进程间的通信
有名管道用于运行于同一系统中的任意两个进程间的通信。
无名管道由pipe()函数创建: int pipe(int fieldis[2]);
当一个管道建立时,它会创建两个文件描述符:
fieldis[0]用于读管道,fieldis[1]用于写管道
管道关闭:关闭管道只需要将这两个文件描述符关闭即可,可以使用普通的close函数逐个关闭。
父进程向管道中写数据,子进程从管道中读数据。
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int pipe_fd[2];
pid_t pid;
char buf_r[100];
char *p_wbuf;
int r_num;
memset(buf_r,0,sizeof(buf_r));
/*创建管道*/
if(pipe(pipe_fd)<0)
{
printf("pipe create error\n");
return -1;
}
/*创建子进程*/
if((pid = fork())==0)
{
printf("\n");
close(pipe_fd[1]);
sleep(2);//为什么要睡眠?
if((r_num = read(pipe_fd[0],buf_r,100))>0)
{
printf("%d numbers read from the pipe is %s\n",r_num,buf_r);
}
close(pipe_fd[0]);
exit(0);
}
else if(pid>0)
{
close(pipe_fd[0]);
if(write(pipe_fd[1],"hello",5)!= -1)
printf("parent write hello\n");
if(write(pipe_fd[1],"world",5)!= -1)
printf("parent write world\n");
close(pipe_fd[1]);
sleep(3);
wait(pid,NULL,0);//等待子进程结束
exit(0);
}
return 0;
}
代码运行结果:
有名管道:与无名管道基本相同,不同点在于:无名管道只能由父子进程使用,但是通过有名管道,不相关的进程也能交换数据。
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#define FIFO_SERVER "/tmp/myfifo"
int main(int argc,char **argv)
{
int fd;
char w_buf[100];
int nwrite;
/*打开管道*/
fd = open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
if(argc == 1)
{
printf("Please,send something:\n");
exit(-1);
}
strcpy(w_buf,argv[1]);
/*向管道写入数据*/
if((nwrite = write(fd,w_buf,100))==-1)
{
if(errno == EAGAIN)
{
printf("The FIFO has not been read yet. Please try later.\n");
}
}
else
{
printf("write %s to the FIFO \n",w_buf);
}
return 0;
}
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#define FIFO "/tmp/myfifo"
int main(int argc,char **argv)
{
int fd;
char r_buf[100];
int n_read;
/*创建管道*/
if((mkfifo(FIFO,O_CREAT|O_EXCL) < 0) && (errno != EEXIST))
printf("cannot create fifoserver\n");
printf("Prepring for reading bytes...\n");
memset(r_buf,0,sizeof(r_buf));
/*打开管道*/
fd = open(FIFO,O_RDONLY|O_NONBLOCK,0);
if(fd == -1)
{
perror("open");
exit(1);
}
while(1)
{
memset(r_buf,0,sizeof(r_buf));
if((n_read = read(fd,r_buf,100)) == -1)
{
if(errno == EAGAIN)
printf("no data yet\n");
}
printf("read %s from FIFO\n",r_buf);
sleep(1);
}
pause();
return 0;
}
https://www.cnblogs.com/52php/p/5840229.html