0

0

Linux --进程间通信--管道

黄舟

黄舟

发布时间:2017-01-18 10:45:55

|

1625人浏览过

|

来源于php中文网

原创

一、进程的间通信的原理
进程间交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据空间拷贝到内核缓冲区,进程2再从内核缓冲区把数据读走。这样就实现了进程间通信。
二、进程通信的进制--管道(pipe)

调用 pipe(int filedes[2])函数在内存中开辟的空间称为管道,它一端读数据一端写数据,通过filedes传出给用户程序的两个描述符,filedes[0]指向读端,filedes[1]指向写端。所以通过read(filedes[0);或者write(filedes),来从管道读或写文件。

三、 用管道实现进程通信的方法

(1)父进程创建管道,得到两个文件描述符指向管道的两端、
(2)父进程调用fork()创建子进程,那么子进程也有两个文件描述符指向管道的两端。
(3)父进程关闭写端,子进程关闭读端,子进程往管道写,父进程读,管道是用环形队列实现的,数据从写端写入,读端读出,这样就实现了进程通信
--代码-----

#include  
 #include  
 int main()  
 {  
   int _pipe[2];  
   int  ret=pipe(_pipe);  
   if(ret < 0)  
   {  
     printf(" pipe()");  
     return 1;  
   }  
   pid_t id=fork();  
   if(id < 0)  
   {  
     printf("fork()");  
     return 2;  
   }  
   else if(id==0)  
   {  
     close(_pipe[0]);  
     char buf[]="hello world";  
     int count=10;  
     while(count)  
     {  
      sleep(1);  
      ssize_t _size=write(_pipe[1],buf,sizeof(buf));  
      if(_size < 0)  
      {  
        printf("write()");  
        return 3;  
      }  
      count--;  
      }  
    
    }else  
    {  
    close(_pipe[1]);  
    char buf[1024];  
    int i=0;  
    while(i++<10)  
    {  
      ssize_t _size=read(_pipe[0],buf,sizeof(buf));  
      if(_size >0)  
      {   
         buf[_size]='\n';  
        printf("%s\n",buf);  
      }  
      else  
      {  
        printf("child is empty or exit") ;  
        break;  
      }  
    }  
    }  
    return 0;  
  }

运行结果:

328.jpg

四、管道的限制

两个进程用一个管道只能实现单进程通信,一个写一个读,不能同时进行读写,如果要让父进程写,子进程读,就必须重新另开一个管道。管道的读写端是通过打开的文件描述符来传递的,所以两个进程必须从父进程那里继承文件描述符。只有两个进程都能访问同一管道时,他们才能通信。

五、管道的4种特殊情况

(1)如果指向管道写端的文件描述符都关闭了,但是仍有进程从管道的读端读数据,那么管道中剩余的数据被读完后,再次read 就会返回0。

(2)如果有指向管道写端的文件描述符没关闭,而持有管道写端的进程也没有向管道中写数据,这时有进程从管道读端读数据,那么管道中剩余的数据都被读取后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回。
(3)如果所有指向管道读端的文件描述符都关闭了,这时有进程向管道的写端write,那么该进程会收到信号SIGPIPE,通常会导致进程异常终止。
(4)如果所有指向管道读端的文件描述符没关闭,但是也不从管道中读取数据,这是如果进程向管道写端写数据,那么在管道被写满时,再写的话就会被阻塞,直到管道中有了空位置才写入数据并返回。

管道的缺点在于是没有名字,因此,只能用于有亲缘关系的进程之间进行通信,为了解决这个问题,又引入了命名管道(FIFO),命名管道提供了路径名与之关联,以FIFO的文件形式存储于文件系统中,所以只要访问该路劲,就能实现进程间的通信。FIFO总是按照先进先出的原则工作,第一个被写入的先出来。
一、命名管道的创建
用mkfifo函数来创建FIFO

int mkfifo(const char *path,mode_t mode);

二、命名管道的使用方法
先调用open()将其打开,要以只读的方式打开,以写的方式打开写入(O_WRONLY)

三、命名管道的程序代码:
client端

#include  
 #include  
 #include  
 #include  
 #include  
 #include  
 #include  
 #include  
 #define _PATH_ "./.tem"  
 int main()  
 {  
   int fd=open(_PATH_,O_RDONLY);  
   if(fd<0)  
   {  
     printf("open error");  
   }  
   char buf[1024];  
   memset(buf,'\0',sizeof(buf));  
   while(1)  
   {  
    int ret =read(fd,buf,sizeof(buf));  
     if(ret>0)  
     {  
       buf[ret]='\n';  
       printf("serve said:%s\n",buf);  
     }  
   }  
   close(fd);  
    return 0;  
 }

serve端

BJXSHOP网上购物系统 - 书店版
BJXSHOP网上购物系统 - 书店版

BJXSHOP购物管理系统是一个功能完善、展示信息丰富的电子商店销售平台;针对企业与个人的网上销售系统;开放式远程商店管理;完善的订单管理、销售统计、结算系统;强力搜索引擎支持;提供网上多种在线支付方式解决方案;强大的技术应用能力和网络安全系统 BJXSHOP网上购物系统 - 书店版,它具备其他通用购物系统不同的功能,有针对图书销售而进行开发的一个电子商店销售平台,如图书ISBN,图书目录

下载
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#define _PATH_ "./.tem"  
int main()  
 {  
   umask(0);  
   int ret = mkfifo(_PATH_,S_IFIFO |0666) ;  
   if(ret<0)  
   {  
     printf("mkfifo error\n");  
     return 1;  
    }  
   int fd=open(_PATH_,O_WRONLY);  
   if(fd<0)  
   {  
     printf("open error");  
   }  
   char buf[1024];  
   memset(buf,'\0',sizeof(buf));  
   while(1)  
   {  
      printf("please iput\n");  
      scanf("%s",buf);  
      int ret =write(fd,buf,strlen(buf)+1);  
      if(ret<0)  
      {  
        printf("write error\n");  
        break;  
      }  
    }  
    close(fd);  
     return 0;  
  }

运行结果:

329.jpg

以上就是Linux --进程间通信--管道的内容,更多相关内容请关注PHP中文网(www.php.cn)!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java连接字符串方法汇总
java连接字符串方法汇总

本专题整合了java连接字符串教程合集,阅读专题下面的文章了解更多详细操作。

7

2026.02.05

java中fail含义
java中fail含义

本专题整合了java中fail的含义、作用相关内容,阅读专题下面的文章了解更多详细内容。

8

2026.02.05

控制反转和依赖注入区别
控制反转和依赖注入区别

本专题整合了控制反转和依赖注入区别、解释、实现方法相关内容。阅读专题下面的文章了解更多详细教程。

11

2026.02.05

钉钉脑图插图教程合集
钉钉脑图插图教程合集

本专题整合了钉钉脑图怎么插入图片、钉钉脑图怎么用相关教程,阅读专题下面的文章了解更多详细内容。

24

2026.02.05

python截取字符串方法汇总
python截取字符串方法汇总

本专题整合了python截取字符串方法相关合集,阅读专题下面的文章了解更多详细内容。

2

2026.02.05

Java截取字符串方法合集
Java截取字符串方法合集

本专题整合了Java截取字符串方法汇总,阅读专题下面的文章了解更多详细操作教程。

1

2026.02.05

java 抽象方法
java 抽象方法

本专题整合了java抽象方法定义、作用教程等内容,阅读专题下面的文章了解更多详细内容。

2

2026.02.05

Eclipse创建jsp文件教程合集
Eclipse创建jsp文件教程合集

本专题整合了Eclipse创建jsp文件、创建jsp项目等等内容,阅读专题下面的文章了解更多详细教程。

26

2026.02.05

java 字符串转数字
java 字符串转数字

本专题整合了java如何字符串转数字相关内容,阅读专题下面的文章了解更多详细教程。

4

2026.02.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8.5万人学习

Git 教程
Git 教程

共21课时 | 3.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号