linux下进程间通信方式之(1)-管道及fork()函数

来源:互联网 发布:淘宝衣服检测 编辑:程序博客网 时间:2024/04/29 13:01
linux下进程间通信方式:
  1. 管道(pipe),流管道(s_pipe)和有名管道(FIFO)
  2. 信号(signal)
  3. 消息队列
  4. 共享内存
  5. 信号量
  6. 套接字(socket)
一、管道

管道,通常指无名管道,是 UNIX 系统IPC最古老的形式。

1、特点:

它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。
它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。
它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

2、原型:
#include <unistd.h>int pipe(int fd[2]);  
当一个管道建立时,它会创建两个文件描述符:fd[0]为读而打开,fd[1]为写而打开。如下图:

要关闭管道只需将这两个文件描述符关闭即可。

3、例子

单个进程中的管道几乎没有任何用处。所以,通常调用 pipe 的进程接着调用 fork,这样就创建了父进程与子进程之间的 IPC 通道。如下图所示:

若要数据流从父进程流向子进程,则关闭父进程的读端(fd[0])与子进程的写端(fd[1]);反之,则可以使数据流从子进程流向父进程。

#include<stdio.h>#include<unistd.h>int main(){    int fd[2];  // 两个文件描述符    pid_t pid;    char buff[20];    if(pipe(fd) < 0)  // 创建管道        printf("Create Pipe Error!\n");    if((pid = fork()) < 0)  // 创建子进程        printf("Fork Error!\n");    else if(pid > 0)  // 父进程    {        close(fd[0]); // 关闭读端        write(fd[1], "hello world\n", 12);    }    else    {        close(fd[1]); // 关闭写端        read(fd[0], buff, 20);        printf("%s", buff);    }    return 0;}

二、fork()

1、定义

计算机程序设计中的分叉函数。返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记;否则,出错返回-1。
fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。
这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本。

2、例子

/*  *  fork_test.c  *  version 1  *  Created on: 2010-5-29  *      Author: wangth  */  #include <unistd.h>  #include <stdio.h>   int main ()   {       pid_t fpid; //fpid表示fork函数返回的值      int count=0;      fpid=fork();       if (fpid < 0)           printf("error in fork!");       else if (fpid == 0) {          printf("i am the child process, my process id is %d/n",getpid());           printf("我是爹的儿子/n");//对某些人来说中文看着更直白。          count++;      }      else {          printf("i am the parent process, my process id is %d/n",getpid());           printf("我是孩子他爹/n");          count++;      }      printf("统计结果是: %d/n",count);      return 0;  } 
运行结果是:

    i am the child process, my process id is 10011
    我是爹的儿子
    统计结果是: 1
    i am the parent process, my process id is 10010
    我是孩子他爹
    统计结果是: 1

 在语句fpid=fork()之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程的几乎完全相同,将要执行的下一条语句都是if(fpid<0)
 为什么两个进程的fpid不同呢,这与fork函数的特性有关。fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
    1)在父进程中,fork返回新创建子进程的进程ID;
    2)在子进程中,fork返回0;
    3)如果出现错误,fork返回一个负值;







原创粉丝点击