linux进程间通讯——管道的使用

在linux中使用的进程间通信(IPC)方法有
1、管道(pipe)和有名管道(FIFO)
2、信号(signal)
3、消息队列
4、共享内存
5、信号量
6、套接字
下面介绍管道的用法:
管道是单向的、先进先出的,它把一个进程的输出和另一个进程的输入连接在一起,一个进程(写进程)往管道尾部写入数据,另一个进程(读进程)在管道首部读取数据。

当管道中的数据被读取时,管道中的这个数据会被删除,当进程读取空管道时会发生阻塞,同理当进程往满管道里写入数据时也会阻塞。

管道分为两类,无名管道(pipe)和有名管道(FIFO),前者用于子进程和父进程之间的通讯,后者用于不同进程之间的通讯。
无名管道的创建使用的是 pipe函数,pipe函数的原型:
int pipe(int filedis[2]);
filedis是一个数组,它含有两个文件描述符,filedis[0]用于读,fileids[1]用于写。
管道使用后是需要关闭的,而管道的关闭只需要使用close函数关闭那两个文件描述符即可。
在创建无名管道时,必须在创建子进程之前创建无名管道,这样子进程才会继承父进程的管道。

  1 #include <stdio.h>
  2 #include <sys/types.h>
  3 #include <unistd.h>
  4 #include <errno.h>
  5 #include <stdlib.h>
  6 #include <string.h>
  7 #include <sys/wait.h>
  8 
  9 int main(int argc, char **argv)
 10 {
 11     int pipe_fd[2];  //创建pipe的文件描述符
 12     char buf[100];
 13     pid_t pid;
 14 
 15     memset(buf,0,sizeof(buf));
 16 
 17     if (pipe(pipe_fd)<0) {   //创建pipe
 18         printf("can not create pipe");
 19         exit(1);
 20     }
 21 
 22     pid = fork();  //创建子进程
 23 
 24     if (pid == 0) {   
 25         close(pipe_fd[0]);
 26         if (write(pipe_fd[1],"test 123456\n",16)<0) {   //往pipe中写入数据
 27             printf("pipe can not write\n");
 28             exit(1);
 29         }
 30         else {
 31             printf("test success\n");
 32         }
 33         close(pipe_fd[1]);
 34 
 35     }
 36     else if (pid > 0) {
 37         close(pipe_fd[1]);
 38         sleep(2);
 39         wait(NULL);   //等待子进程运行完毕
 40         if (read(pipe_fd[0],buf,100)<0) {   //从pipe中读取数据
 41             printf("can not read\n");
 42             exit(1);
 43         }
 44         else {
 45             printf("read %s from pipe\n",buf);
 46         }
 47         close(pipe_fd[0]);
 48     }
 49 
 50     return 0;
 51 }

有名管道用于不同进程之间的通讯,因此需要创建两个函数,一个fifo_read.c,一个fifo_write.c,在fifo_read.c中创建fifo。
fifo_read.c

  1 #include <unistd.h>
  2 #include <sys/wait.h>
  3 #include <sys/types.h>
  4 #include <errno.h>
  5 #include <stdio.h>
  6 #include <stdlib.h>
  7 #include <string.h>
  8 
  9 
 10 int main(int argc, char **argv)
 11 {
 12     int fd;
 13     char buf_r[100];
 14     int acc;
 15 
 16     memset(buf_r,0,sizeof(buf_r)); 
 17     if ((acc=access(FIFO,F_OK))==-1) {  //判断FIFO文件是否已创建
 18         if (mkfifo(FIFO,0777) < 0) {   //创建FIFO文件
 19             printf("fifo can not create\n");
 20             exit(1);
 21         }
 22     }
 23     printf("acc = %d\n",acc);
 24 
 25     printf("read byte......\n");  
 26     fd = open(FIFO,O_RDONLY | O_NONBLOCK,0); //打开FIFO文件
 27     printf("open\n");  //测试
 28     if (fd == -1) {
 29         printf("can not open fifo\n");
 30     }
 31     printf("while\n");
 32     while (1) {
 33         memset(buf_r,0,sizeof(buf_r));
 34         if (read(fd,buf_r,100) == 0) {   //读数据
 35             printf("no data\n");
 36         }
 37 
 38         printf("read %s from fifo\n",buf_r);
 39         sleep(2);
 40     }
 41     pause();
 42     return 0;
 43 }


fifo_write.c

  1 #include <sys/types.h>
  2 #include <sys/stat.h>
  3 #include <fcntl.h>
  4 #include <unistd.h>
  5 #include <stdio.h>
  6 #include <stdlib.h>
  7 #include <string.h>
  8 #define FIFO "/home/book/c/fifo/myfifo"
  9 
 10 int main(int argc ,char **argv)
 11 {
 12     int fd;
 13 
 14     fd = open(FIFO,O_WRONLY | O_NONBLOCK,0);
 15     if (fd == -1) {
 16         printf("can not open fifo\n");
 17         exit(1);
 18     }
 19     if (write(fd,"hello linux", 14)<0) {
 20         printf("write error\n");
 21         exit(1);
 22     }
 23     else {
 24         printf("write succse\n");
 25     }
 26 
 27     return 0;
 28 }

开打两个命令窗口分别运行读函数和写函数

在这里插入图片描述
在使用有名管道时,出现了无法创建FIFO的问题,在排查后发现,由于FIFO文件只能创建一次,当第二次运行fifo_read时,FIFO文件已存在,程序就会出错退出,因此我使用了access函数来判断FIFO文件是否已创建。
出现O_RDONLY未定义等问题,可添加头文件
#include <sys/stat.h>
#include <fcntl.h>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值