Linux下利用管道进行父进程与子进程通信
无名管道只能在有亲缘关系的进程通信,有名管道可以在任意进程通信。
- 无名管道
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv){
int rd,fd[2];
FILE *fp;
pid_t pid;
//创建管道
if(pipe(fd)==-1){
printf("faild");
return 0;
}
//创建进程
pid = fork();
if(pid <0){
printf("fork create is faild [%s]\n",strerror(errno));
return 0;
}
else if(pid == 0){ //这里就进入了子进程
//关闭子进程的读通道
close(fd[0]);
//重定向fd[1]为标准输出,会先关闭标准输出
if(dup2(fd[1],STDOUT_FILENO) != STDOUT_FILENO){
printf("dup2 is faild");
return -1;
}
execl("/sbin/ifconfig","ifconfig","eth0",NULL);
}
else{
sleep(2);
char buf[100];
//关闭父进程的写通道
close(fd[1]);
while(read(fd[0],buf,10) != '0'){
printf("%s\n",buf);
sleep(1);
memset(buf,0,sizeof(buf));
}
}
}
这里注意的是首先要在父进程创建一个管道,然后在创建fork,因为必须在父进程创建了pipe让子进程继承之后子进程的程序中才能使用管道,不然写反了就会让父子进程都创建一个管道,另外在每个进程中必须关闭一个读或者写通道。
- 有名管道
首先读端或者写端使用mkfifo创建一个管道文件,然后用写、读端使用open函数打开即可。
写端
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define FIFO_NAME "myfifo" // 定义FIFO文件的$
#define BUFFER_SIZE 256 // 定义缓$
int main(int argc, char *argv[])
{
int fd;
char msg[1024];
char buf[BUFFER_SIZE];
int buflen;
fd = open(FIFO_NAME, O_WRONLY); // 打开这个文件
if(-1 == fd)
{
printf("open error!\n");
return -1;
}
printf("please input message into file:");
gets(msg);
/* 将消息写入FIFO文件当中 */
sprintf(buf, "%s", msg);
buflen = write(fd, buf, BUFFER_SIZE);
if(buflen <= 0)
{
printf("write error!\n");
return -1;
}
else
{
printf("Write to fifo : %s\n", buf);
}
close(fd); // 关闭这个文件
return 0;
}
读端
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define FIFO_NAME "myfifo" // 定义FIFO文件的名称
#define BUFFER_SIZE 256 // 定义缓冲区的大小
/* 创建FIFO文件,并以阻塞方式读取FIFO文件当中的内容
*
*/
int main(void)
{
int ret;
int fd;
char buf[BUFFER_SIZE];
int buflen;
/* 创建FIFO文件 */
if(-1 == access(FIFO_NAME, F_OK)) // 判断FIFO文件是否存在
{
ret = mkfifo(FIFO_NAME, 0666); // 以可读可写方式创建一个FIFO文件
if(-1 == ret)
{
printf("mkfifo error!\n");
return -1;
}
}
fd = open(FIFO_NAME, O_RDONLY); // 打开这个文件
if(-1 == fd)
{
printf("open error!\n");
return -1;
}
/* 以阻塞的方式读取文件当中的内容 */
while(1)
{
memset(buf, 0, BUFFER_SIZE);
buflen = read(fd, buf, BUFFER_SIZE);
if(buflen > 0)
{
buf[buflen] = '\0';
if(!strcmp("quit", buf)) // 如果读到的信息是quit,则
退出
{
return 0;
}
else // 将读取的信息打印出来
{
printf("Read from fifo : %s\n", buf);
}
}
}
close(fd); // 关闭这个文件
return 0;
}