Linux 进程间通信
共享文件
两个进程可以通过共享文件的方式进行通信,即一个进程在文件中写入消息,另外一个进程从文件中读出信息。这两个进程有无血缘关系均可以。但是通过共享同一个文件进行进程间通信的缺点是,两个进程的读写同步问题,即一个进程写的慢另外一个进程读的快的时候会读不到内容。示例代码如下:
int main(int argc, const char* argv[])
{
int fd = open("My_file", O_CREAT | O_RDWR,0664);
if(-1 == fd){
perror("open My_file error!");
exit(1);
}
pid_t pid = fork();//创建子进程
if(-1 == pid){
perror("fork error!");
exit(1);
}
if(pid > 0){ //父进程写
char *temp = "The first test IPC msg by file is successfuly!\n";
write(fd, temp, strlen(temp)+1);
close(fd);
}else if(0 == pid){ //子进程读
sleep(1); //睡眠1秒的原因是为了保证此时父进程完成写操作。
char read_buf[1024];
lseek(fd, 0, SEEK_SET); //保证文件指针在文件头部
int len = read(fd, read_buf, sizeof(read_buf));
printf("%s\n",read_buf);
close(fd);
}
return 0;
}
匿名管道pipe
匿名管道pipe的实质是内核的缓冲区,它不占用磁盘空间。 一个pipe分为读写两部分,有读和写两个文件描述符,pipe是半双工的一个进程写的时候要把它的读端文件描述符关掉,读的时候要把他的写端文件描述符关掉。pipe默认是阻塞的,写端进程没有写入数据的时候读端进程不用再刻意sleep去等待,而是一直阻塞在那里等待直到写端进程写入。pipe实现是以环形队列形式实现的,所以数据只能读一次(两个进程只有一个进程能从pipe中读消息,读完后队列中这条消息就没有了。pipe在进程结束时有系统回收。匿名管道特点是只能进行有血缘关系的进程间通信,没有血缘关系的进程间无法使用pipe进行通信。示例代码如下:
int main(int argc, const char* argv[])
{
int fd[2]={0};
int ret = pipe (fd);//fd[0]为读端,fd[1]为写端
if(-1 == ret){
perror("pipe error!");
exit(1);
}
pid_t pid = fork();//创建子进程
if(-1 == pid){
perror("fork error!");
exit(1);
}
if(pid > 0){ //父进程写,关闭读端
close(fd[0]);
char *temp = "The first test IPC msg by pipe is successfuly!\n";
write(fd[1], temp, strlen(temp)+1);
close(fd[1]);
}else if(0 == pid){ //子进程读,关闭写端
close(fd[1]);
char read_buf[1024];
int len = read(fd[0], read_buf, sizeof(read_buf));
printf("%s\n",read_buf);
close(fd[0]);
}
return 0;
}
有名管道fifo
有名管道fifo的实质是磁盘一个大小为0的文件映射一个内核缓冲区,它不占用磁盘空间,所以fifo在磁盘上空间永远为0。fifo默认是阻塞的,写端没有写入数据的时候读端不用可以sleep去等待,而是一直阻塞在那里等待写端写入。fifo是伪文件,它可以使用open、close、read、write等文件IO操作但是不能使用lseek操作。fifo特点是能进行无血缘关系的进程间通信。示例代码如下:
写端代码:
int main(int argc, const char* argv[])
{
if(argc < 2){
printf("The right step is: ./a.out fifoname\n");
exit(1);
}
//判断文件是否存在
int ret = access(argv[1], F_OK);
if(-1 == ret){
ret = mkfifo(argv[1], 0664);
if(-1 == ret){
printf("mkfifo error!\n");
exit(1);
}
printf("Create %s fifo sucess!\n",argv[1]);
}
int fd = open(argv[1], O_WRONLY);
if(-1 == fd){
printf("open error!\n");
exit(1);
}
while(1){
sleep(1);