• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Linux –进程间通信–管道

php 搞代码 4年前 (2022-01-22) 19次浏览 已收录 0个评论

一、进程的间通信的原~来1源gaodai#ma#com搞*代#码1网搞代gaodaima码
进程间交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据空间拷贝到内核缓冲区,进程2再从内核缓冲区把数据读走。这样就实现了进程间通信。
二、进程通信的进制–管道(pipe)

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

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

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

#include<stdio.h>   #include<unistd.h>   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;    }

运行结果:

四、管道的限制

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

五、管道的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<stdio.h>   #include<error.h>   #include<stdlib.h>   #include<string.h>   #include<fcntl.h>   #include<sys/types.h>   #include<sys/stat.h>   #include<unistd.h>   #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端

#include<stdio.h>  #include<stdlib.h>  #include<string.h>  #include<fcntl.h>  #include<sys/types.h>  #include<sys/stat.h>  #include<unistd.h>  #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;    }

运行结果:

以上就是Linux –进程间通信–管道的内容,更多相关内容请关注搞代码(www.gaodaima.com)!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Linux –进程间通信–管道

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址