1、IPC(Internal Processes Communication)
进程间通讯--->实际上数据的交换。
通过全局变量的方式实现不了进程间通讯
因为进程内存空间,都是相互独立的,不能通过这种方式去互相访问。
进程间通讯的方式:
1、内存映射,内存共享。
2、通过读写文件的方式。这种效率比较低。
3、信号。
4、消息队列。
5、信号量。
6、管道。无名管道(这个管道没有节点,不存在与文件系统里面,它存在于内核内,只限与有亲缘关系的进程间实现通讯)
有名管道(有一个节点存在于文件系统当中,通过这个节点作为一个桥梁,实现通讯)
无名管道
无名管道的建立:
SYNOPSIS
#include <unistd.h>
int pipe(int pipefd[2]);
返回值:成功返回0,失败返回-1,并且可以通过perror把错误码打印出来。
#include <fcntl.h> /* Obtain O_* constant definitions */
#include <unistd.h>
1) 创建管道 pipe。
2)关闭无关的端口。(本身是全双工的,但是我们两个进程用一个管道通讯,就要按某种同步方式去读写数据,否则造成数据的错误,所以我们人为把其中一端关闭 close(fd))
3) int pipefd[2]这里代表的是两个文件描述符,pipefd[0]--->读 read(pipefd[0], buf, len );
pipefd[1]--->写 write(pipefd[1], buf, len);
4) 使用结束后关闭对应的端口。
无名管道间的双向通信
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int pipefd[2];
int pipefd2[2];
pid_t pid;
int r;
char buf_w[128],buf_r[128];
memset(buf_w,0,128);
memset(buf_r,0,128);
if(pipe(pipefd)<0)
{
perror("creat pipe faile");
exit(-1);
}
if(pipe(pipefd2)<0)
{
perror("creat pipe faile");
exit(-1);
}
pid=fork();
if(pid<0)
{
perror("fork error");
exit(-1);
}
if(pid==0)
{
printf("i am chile process\n");
printf("please input:\n");
close(pipefd[0]);
scanf("%s",buf_w);
write(pipefd[1],buf_w,strlen(buf_w));
memset(buf_w,0,128);
close(pipefd[1]);
close(pipefd2[1]);
read(pipefd2[0],buf_r,128);
printf("read from parent %s\n",buf_r);
memset(buf_r,0,128);
close(pipefd2[0]);
exit(0);
}
else
{
close(pipefd[1]);
read(pipefd[0],buf_r,128);
printf("i am parent process\n");
printf("read from child %s\n",buf_r);
memset(buf_r,0,128);
close(pipefd[0]);
close(pipefd2[0]);
printf("plese input:\n");
scanf("%s",buf_w);
write(pipefd2[1],buf_w,strlen(buf_w));
memset(buf_w,0,128);
close(pipefd2[1]);
waitpid(pid,NULL,0);
exit(0);
}
return 0;
}
有名管道:
在文件系统种,有个管道的节点。然后两个不同进程,可以通过系统IO所提供的接口函数,去实现通讯。
open
read/write
close
NAME
mkfifo - make FIFOs (named pipes) 首先创建一个有名管道的节点。对于节点的操作就是系统IO的操作
mkfifo(char *name,mode_t mode); 第一个参数为创建节点的名字,第二个参数为创建这个节点的访问权限,通常为0644;//第一个参数必须是个文件名,不能是目录,创建后能在相应的目录里面找到这个节点。
/* According to POSIX.1-2001 */
#include <sys/select.h>
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
int nfds, 这个是我们需要监听的fd最大值加1,
fd_set *readfds这个参数是监听可读fd
fd_set *writefds这个是监听可写的fd。