频道栏目
首页 > 系统 > Linux > 正文
Linux进程通信(System V)第一节------>管道pipe
2012-03-20 12:57:31      个评论      
收藏   我要投稿

简介:

 

一.

#include <unistd.h>

 

int pipe(int fd[2]); 

  //!>注意参数是fd[0]是读的文件描述符,fd[1]是用来写的文件描述符

 

一般用于 “父子进程” 之间的通信!因为pipe是没有标志的,所以只能在一个进程集中运作!

 

“单向pipe”:

      父进程创建好 pipe 后,同时通过 fork() 创建一个子进程,然后父进程就可以关闭自己这端的“读进程”,因为  父进程就是将数据写入子进程的,所以无须 “读”,然后子进程就关闭自己的“写”,这样就形成一个 “单向” 的 pipe。

 

“双向pie”:( 可以用于CS )

     创建两个pipe就可以了,其实也就是相当于加一个 “单向”pipe

 

二.

    关于 fork函数

    对于fork的返回值:对于父进程返回的是子进程的ID号(肯定是大于0的),对于子进程返回的是0

所以可以通过 if( pid = fork() > 0 ) 和 if( pid == 0 )来判断是父进程还是子进程在执行

 

三.

    其他

    对于 pipe而言,创建 ok后,在子进程和父进程中都会有一个此管道(pipe)的读和写的接口!操作value是相同的fd[0]和fd[1]

 

对于 test.c 中的为例:

      由于是多进程编程,那么对于test.c代码而言,应该是有“子进程”和“父进程”都可以执行的!也就是说在fork后程序就是分成两部分,主进程和子进程。

      我们可以测试:

       如果是printf("on ");那么可以输出两次 on,分别是父进程和子进程输出的,但是if是printf(" on \n");那么只输出一次。

      原因:printf的机制是:遇到"\n"就会直接输出,if没有,那么只是储存在缓存中,然后一起输出。

         所以if有"\n",那么就是父进程先让其输出了,那么在父进程的空间空就没有保存printf中的缓存数据了!!!所以子进程就没有继承到,所以就不会输出!!!

         

       也就是说:父进程的printf 空间缓存区也被继承!!!!!!!!!!!!!!!!!!!!!

 

       getpid():获得本进程的ID

       getppid():获得父进程的ID   

 

四.参考代码:

 

//!>

//!> 单向 pipe实例   

//!>

 

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <stdio.h>

 

int g_num =0;               //!> 全局变量:用来测试父进程和子进程的独立空间

                  //!> 我们可以知道全局变量在子进程和父进程中是有自己的独立空间的!

int main()

{

    int n,fd[2];            //!> fd 是描述符

    pid_tpid;            //!> 保存的是创建的进程的 ID

    charline[100];            //!> 相当于是一个缓存

 

    int num = 0;            //!> 也是独立的~~~

 

    printf(" on");            //!> ATTENTION  printf(" on\n");

 

    if( pipe( fd) < 0)         //!> 此处就是创建pipe,成功则返回0,if失败则返回-1

    {

      exit(0);

    }

 

   

    if( ( pid =fork() ) < 0)      //!> 创建子进程

    {

      exit(0);

    }

    else if( pid> 0 )

    {

      close(fd[0]);

       write(fd[1],"I am your father...\n", 19);

      

      g_num++;

       num++;

      printf("\nFather g_num:%d    num: %d\n", g_num,num);   

 

       printf("\nMYID : %d   Parent ID : %d  \n", getpid(), getcpid());

    }

   else               //!> == 0 当前进程(也就是刚刚创建的子进程)

    {

       close( fd[1]);

       n = read(fd[0], line, 100 );

       write(STDOUT_FILENO, line, n );    //

 

      g_num++;

       num++;

      printf("\nChild g_num:%d    num: %d\n", g_num, num);

 

       printf("\nMYID : %d   Parent ID : %d  \n", getpid(), getppid());

    }

 

    printf(" ok");            

   

    return0;

}

 

 

//!>

//!> 双向 pipe 实例

//!>

 

#include <sys/types.h>

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

#include <string.h>

 

int main()

{

    int fd_1[2],fd_2[2];                  //!> 双向 pipe 的 values、

    charcData[100];

    pid_tpid;

   

    if( pipe(fd_1 ) < 0)                  //!> create the pipe_1

    {

      printf("\n创建第一个 pipe 失败!\n");

       exit( 0);

    }

   

    if( pipe(fd_2 ) < 0)               //!> create the pipe_2

    {

      printf("\n创建第二个 pipe 失败!\n");

       exit( 0);

    }

 

    if( ( pid =fork() ) < 0)               //!> false to create a new process

    {

      printf("\n创建进程失败!\n");

       exit( 0);

    }

    else if( pid== 0 )                  //!> 也就是fork返回的子进程...

    {

      //!> 子进程也需要发送 data 到 pipe

       close(fd_2[0] );

       char str[30]= "I am your child!";

       write(fd_2[1], str, strlen( str ));      //!> 第二个pipe是子进程发送data,父进程接受data

      

      //!> 子进程也需要接受父进程的 data

       close(fd_1[1] );

       int n =read( fd_1[0], cData, 100);      //!> 第一个pipe是父进程发送data,子进程接受data

       write(STDOUT_FILENO, cData, n );

    }

   else                        //!> fork 返回的是子进程的ID,肯定是大于0的,所以此处执行的是父进程的code

    {

      //!> 父进程也需要发送 data 到 pipe

       close(fd_1[0] );

       char str[30]= "I am your father!";

       write(fd_1[1], str, strlen( str ));      //!> 第二个pipe是子进程发送data,父进程接受data

      

      //!> 父进程也需要接受父进程的 data

`       close(fd_2[1] );

       int n =read( fd_2[0], cData, 100);      //!> 第一个pipe是父进程发送data,子进程接受data

       write(STDOUT_FILENO, cData, n );

    }

 

    return0;

}

 

 

 

 

摘自shanshanpt的专栏

点击复制链接 与好友分享!回本站首页
相关TAG标签 管道 进程 第一节
上一篇:CentOs下安装java环境和jdk
下一篇:Linux进程通信(System V)第二节------>FIFO
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站