Linux C 进程间的管道通信

1、进程间的通信方式

       a、管道通信:无名管道、有名管道

       b、信号通信:包括信号的发送、接收和处理

       c、IPC(Inter-Process Communication):共享内存、消息队列、信号灯

*** < 以上是单机模式下的进程通信,只有一个Linux内核 > ***

        d、Socket通信:存在于一个网络中的两个进程间的通信(两个Linux内核)


2、管道文件、字符设备、块设备、套接字:只有文件节点,不占磁盘空间

      普通文件、链接文件(软链接)、目录文件:不仅有inode号,还占磁盘空间


3、管道通信

      A、无名管道

                     只能实现父子进程(亲缘关系)间通信

            fork() 函数创建父子进程,库<sys/types.h>,子进程是对父进程的完全拷贝,包括管道的文件描述符

                       例:pid_t pid;              pid = fork();        if(pid == 0){   }        if(pid > 0){      }

            pipe() 函数创建无名管道,库<unistd.h>,无名管道 没有文件名、打开方式和权限,只有两个文件描述符:fid[0] 读、fid[1] 写

                        (打开一个进程时,系统已自动创建了3个文件描述符:0、1、2,所以,fid从3开始计)

                        例:int fid[2];              int ret;                ret = pipe(fid);

                                write(fid[1], &process_inter, sizeof(process_inter));   //写到哪里去、写什么、写多少个

                                read(fid[0], &process_inter, 4);   //从哪里读、读到哪里去、读多少个

            管道是创建在内存中的,进程结束,空间释放,管道就不存在了

            管道中的内容读完了,就删除了(队列)

            读阻塞:如果管道中没有东西可读又继续读,则会读阻塞

            写阻塞:如果管道中写满了又继续写,则会写阻塞


      B、有名管道

                    可实现非父子进程(非亲缘关系)间通信

             mkfifo() 函数 创建管道文件节点

                     例:int ret;            ret = mkfifo("./myfifo", 0777);     文件路径及文件名、权限模式

             open() 函数 在内核创建管道空间

                     例:int fd;               fd = open("./myfifo", O_WRONLY);        或   fd = open("./myfifo", O_RDONLY);

                              write(fd, &process_inter, sizeof(process_inter));   //写

                              read(fd, &process_inter, 1);   //读


代码 - 父子进程 & 无名管道:

  1 #include <stdio.h>
  2 #include <sys/types.h>  //进程 fork()
  3 #include <unistd.h>     //管道 pipe()
  4 
  5 int main()
  6 {
  7         pid_t pid;      //进程类型
  8         int fid[2];
  9         int ret;
 10 
 11         int process_inter = 0;
 12 
 13         ret = pipe(fid);        //管道  先在内核空间创建管道,确保 父子进程 是操作同一个管道
 14         if(ret < 0)
 15         {
 16                 printf("pipe create failure.\n");
 17                 return -1;
 18         }
 19         printf("pipe create success. fid[0] = %d fid[1] = %d\n",fid[0],fid[1]);
 20 
 21         pid = fork();   //父子进程
 22         if(pid == 0)    //子进程 对父进程 进行完全拷贝
 23         {
 24                 int i = 0;
 25                 printf("***child process fid = %d\n",pid);      //子进程号 为0
 26                 read(fid[0],&process_inter,4);
 27                 while(process_inter == 0);
 28                 while(i < 5)
 29                 {
 30                         printf("this is child proocess %d\n",i);
 31                         i++;
 32                         usleep(100);
 33                 }
 34         }
 35         if(pid > 0)     //父进程
 36         {
 37                 int i = 0;
 38                 printf("***parent process fid = %d\n",pid);     //父进程号
 39                 for(i = 0; i < 5; i++)
 40                 {
 41                         printf("parent process %d\n",i);
 42                         usleep(90);
 43                 }
 44                 process_inter = 1;
 45                 write(fid[1],&process_inter,sizeof(process_inter));
 46                 //while(1);
 47         }
 48 
 49         return 0;
 50 }

执行:父子进程 & 无名管道



代码:非亲缘进程 & 有名管道 -- 创建管道节点

  1 #include <stdio.h>
  2 
  3 int main()
  4 {
  5         int ret;
  6         //管道文件、字符设备、块设备、套接字 只有文件节点,不占磁盘空间
  7         ret = mkfifo("./myfifo",0777);  //mkfifo()只是创建了管道文件节点,并没有在内核空间创建管道空间
  8         //mkfifo()创建管道节点;open()在内核创建管道空间
  9         if(ret < 0)
 10         {
 11                 printf("myfifo create failure.\n");
 12                 return -1;
 13         }
 14 
 15         printf("myfifo create success.\n");
 16         return 0;
 17 }


代码:非亲缘进程 & 有名管道 -- 进程1

  1 #include <stdio.h>
  2 #include <fcntl.h>      //open()、read()、write()
  3 
  4 int main()
  5 {
  6         int fd;
  7         int i;
  8         int process_inter = 0;  //标识
  9 
 10         //open()在内核创建管道空间
 11         fd = open("./myfifo",O_WRONLY); //文件路径及文件名、权限模式
 12         if(fd < 0)
 13         {
 14                 printf("myfifo open failure.\n");
 15                 return -1;
 16         }
 17         printf("myfifo open success.\n");
 18 
 19         for(i = 0; i < 5; i++)
 20         {
 21                 printf("first process i = %d\n",i);
 22                 usleep(100);
 23         }
 24         process_inter = 1;      //标识设为1
 25         write(fd, &process_inter, sizeof(process_inter));       //写入管道。写到哪里去、写什么、写多少个
 26         return 0;
 27 }

代码:非亲缘进程 & 有名管道 -- 进程2

  1 #include <stdio.h>
  2 #include <fcntl.h>      //open()、write()、read()
  3 
  4 int main()
  5 {
  6         int fd;
  7         int i;
  8         char process_inter;
  9 
 10         fd = open("./myfifo",O_RDONLY); //open():文件路径及文件名、权限模式
 11         if(fd < 0)
 12         {
 13                 printf("myfifo open failure.\n");
 14                 return -1;
 15         }
 16         printf("myfifo open success.\n");
 17 
 18         read(fd, &process_inter, 1);    //read()读取管道中的内容:从哪里读、都到哪里去、读多少个
 19 
 20         while(process_inter == 0);      //等待,直到 从管道中读取数值1
 21 
 22         for(i = 0; i < 5; i++)
 23         {
 24                 printf("this is second process i = %d\n",i);
 25                 usleep(100);
 26         }
 27         return 0;
 28 }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值