码迷,mamicode.com
首页 > 系统相关 > 详细

进程通信

时间:2016-04-10 01:33:16      阅读:311      评论:0      收藏:0      [点我收藏+]

标签:匿名管道

通信:因为进程有强大独立性,当想把自己数据交给另一个进程,需要通信。

通信本质:让不同进程看到相同资源。

技术分享

  1. 匿名管道:管道:通过某种机制传递资源(数据),匿名管道只适用于有血缘关系的进程,一般用于父,子进程通信。

    a.创建管道

    b.创建子进程

    c.父,子进程关闭自己不需要的文件描述符

    注意:匿名管道提供单向通信,父读子写或父写子读,若要实现双向通信,可再创建一个管道。

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<stdlib.h>
int main()
{
    int _pipefd[2]={-1,-1};
    int ret=pipe(_pipefd);
    if(ret==-1)
    {
        perror("pipe");
        return 2;
    }
    pid_t id=fork();
    if(id<0)
    {
        perror("fork");
        return 2;
    }
    else if(id==0)
   {
        close(_pipefd[0]);
        char buf[]="hello world";
        int count=5;
        while(count--)
        {
            write(_pipefd[1],buf,strlen(buf));
            sleep(1);
        }
   }
   else
  {  
       close(_pipefd[1]);
       char buf[1024]={0};
       int count=5;
       while(count--)
      {
          memset(buf,‘\0‘,sizeof(buf));
          ssize_t _size=read(_pipefd[0],buf,sizeof(buf)-1);
          buf[_size]=‘\0‘;
          printf("buf:%s\n",buf);
      }
   }
   return 0; 
}

使用管道需注意以下四种情况:

1.如果所有指向管道写端的文件描述符都关闭仍然有进程从管道的读端读数据,那么管道中剩余的数据都被读取后,再次read会返回0,就像读到文件末尾一样。

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<unistd.h>
  4 #include<sys/types.h>
  5 #include<stdlib.h>
  6 int main()
  7 {
  8     int _pipefd[2]={-1,-1};
  9     int ret=pipe(_pipefd);
 10     if(ret==-1)
 11     {
 12         perror("pipe");
 13         return 2;
 14     }
 15
 16     pid_t id=fork();
 17     if(id<0)
 18     {
 19         perror("fork");
 20         return 2;
 21     }
 22     else if(id==0)
 23    {
 24         close(_pipefd[0]);
 25         char buf[]="hello world";
 26         int count=5;
 27         int i=0;
 28         while(count--)
 29         {
 30             if(i==3)
 31             {
 32                 printf("I want sleep\n");
 33                 break;
 34             }
 35             write(_pipefd[1],buf,strlen(buf));
 36             sleep(1);
 37             i++;
 38         }
 39         close(_pipefd[0]);
 40     }
 41     else
 42     {
 43         close(_pipefd[1]);
 44         char buf[1024]={0};
 45         int count=5;
 46         while(count--)
 47         {
 48             memset(buf,‘\0‘,sizeof(buf));
 49             ssize_t _size=read(_pipefd[0],buf,sizeof(buf)-1);
 50             if(_size>0)
 51             {
 52             //  buf[_size]=‘\0‘;
 53                 printf("buf:%s\n",buf);
 54             }
 55         }
 56     }
 57     //printf("%d ,%d \n",_pipefd[0],_pipefd[1]);
 58     return 0;
 59 }

2.如果有指向管道写端的文件描述符没关闭,持有管道写端的进程也没有向管道中写数据,这时有进程从管道读端读数据,那么管道中剩余的数据都被读取后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回。

   //修改子进程代码为
     else if(id==0)
 23     {
 24         close(_pipefd[0]);
 25         char buf[]="hello world";
 26         int count=5;
 27         int i=0;
 28         while(count--)
 29         {
 30             if(i==3)
 31             {
 32                 sleep(10);
 33                 //printf("I want sleep\n");
 34                // break;
 35             }
 36             write(_pipefd[1],buf,strlen(buf));
 37             sleep(1);
 38             i++;
 39         }
 40 //      close(_pipefd[0]);
 41     }

3.如果所有指向管道读端的文件描述符都关闭了,这时有进程向管道的写端write,那么该进程会收到信号SIGPIPE,通常会导致进程异常终止

//修改父进程中代码为:
  else
 44     {
 45         close(_pipefd[1]);
 46         char buf[1024]={0};
 47         int count=5;
 48         while(count--)
 49         {
 50             if(count==3)
 51                 close(_pipefd[0]);
 52             memset(buf,‘\0‘,sizeof(buf));
 53             ssize_t _size=read(_pipefd[0],buf,sizeof(buf)-1);
 54             if(_size>0)
 55             {
 56             //  buf[_size]=‘\0‘;
 57                 printf("buf:%s\n",buf);
 58             }
 59         }
 60         int status=0;
 61         pid_t _pid=waitpid(id,&status,0);
 62         printf("waitpid: %d,return status:%d\n",id,status&0xff);
 63}

4.如果有指向管道读端的文件描述符没关闭,持有管道读端的进程也没有从管道中读数据,这时有进程向管道写端写数据,那么在管道被写满时再次write会阻塞,直到管道中有空位置了才写入数据并返回。 

//修改父进程中代码为:
  else
 44     {
 45         close(_pipefd[1]);
 46         char buf[1024]={0};
 47         int count=5;
 48         while(count--)
 49         {}
 50         int status=0;
 51         pid_t _pid=waitpid(id,&status,0);
 52         printf("waitpid: %d,return status:%d\n",id,status&0xff);
 53}


本文出自 “小止” 博客,请务必保留此出处http://10541556.blog.51cto.com/10531556/1762101

进程通信

标签:匿名管道

原文地址:http://10541556.blog.51cto.com/10531556/1762101

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!