Linux编程进程之间通信
1.匿名管道(Pipes)
管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。通常用于父进程和子进程之间。
管道的实现依赖于内核中的缓冲区。
示例中,创建一个父进程和子进程,父进程会通过管道向子进程发送一条消息,子进程负责从管道中读取消息并打印出来。
#include <unistd.h>
#include<sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
//写消息
void Write(int pid, int wfd)
{
char buf[100] = {0};
while (true)
{
printf("please write your new message:\n");
//scanf("%s", buf);
if (fgets(buf, sizeof(buf), stdin) == NULL)//获取标准输入
{
fprintf(stderr, "get stdin erro!!\n");
}
if (buf[strlen(buf) - 1] == '\n')//判断gets获得的字符串是否带有回车符
{
buf[strlen(buf) - 1] = '\0';
}
if (write(wfd, buf, strlen(buf)) < 0)
{
fprintf(stderr, "pid = %d : write is faild\n", pid);
}
printf("pid:%d process set message:%s\n", pid, buf);
sleep(1);
}
}
//读消息
void Read(int pid, int rfd)
{
char buf[100] = {0};
int len = 0;
while (true)
{
printf("pid = %d, wait get new message:\n", pid);
while ((len = read(rfd, buf, sizeof(buf) - 1)) > 0)
{
buf[len] = '\0';
printf("pid = %d: %s\n", pid, buf);
}
sleep(1);
}
}
int main()
{
int fd[2]; //文件描述符,用于管理
pid_t child_pid; //用于存储子进程ID
//创建一个匿名管道
if (pipe(fd) == -1)
{
perror("Pipe Failed");
exit(EXIT_FAILURE);
}
//创建子进程
child_pid = fork();
if (child_pid < 0)
{
fprintf(stderr, "child process creat fail !!!\n");
}
else if(child_pid > 0)//父进程
{
pid_t pid = getpid();
close(fd[0]);
Write(pid, fd[1]);
exit(1);
}
else//子进程
{
pid_t pid = getpid();
close(fd[1]);
Read(pid, fd[0]);
exit(1);
}
return 0;
}
2.命名管道(Named Pipes/FIFOs)
命名管道克服了普通管道的一个限制,即它可以在没有血缘关系的进程间使用。
命名管道存在于文件系统中,因此可以通过路径名访问。
生产者
#include <unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#define FIFO_NAME "/tmp/fifo"
//写消息
void Write(int pid, int wfd)
{
char b