Linux之间进程通信


必备基础: fork() 创建一个与之前完全一样的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。

一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

// fork() study example 1
#include <unistd.h> #include <stdio.h> int main () { pid_t fpid; //fpid表示fork函数返回的值 int count=0; // fork 会将这个变量存在两个不同的内存中,所以两次count的值都是 1 ,而不是 1,2 。 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; }

运行结果:

在for之前只有一个进程执行代码,但是在fork之后就会再创建一个进程去同时执行这段代码。

程序通过fork的返回值fpid判断是子进程还是父进程,还是创建进程失败。

fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
    1)在父进程中,fork返回新创建子进程的进程ID;  //相当于父进程指向自己的子进程,而子进程没有孩子进程可以指向。
    2)在子进程中,fork返回0;
    3)如果出现错误,fork返回一个负值;

fork出错可能有两种原因:
    1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。
    2)系统内存不足,这时errno的值被设置为ENOMEM。

#include <unistd.h>  
#include <stdio.h>  
int main(void)  
{  
   int i=0;  
   printf("i son/pa ppid pid  fpid\n");  
   //ppid指当前进程的父进程pid  
   //pid指当前进程的pid,  
   //fpid指fork返回给当前进程的值  
   for(i=0;i<2;i++){  
       pid_t fpid=fork();  
       if(fpid==0)  
           printf("%d child  %4d %4d %4d\n",i,getppid(),getpid(),fpid);  
       else  
           printf("%d parent %4d %4d %4d\n",i,getppid(),getpid(),fpid);  
   }  
   return 0;  
}   

1. 在执行第一个循环时: 

  pid=5944 的进程 ,创建了 一个子进程 5945 

2. 第二次循环中:

  5944 的进程穿件了  pid=5946的子进程

  5945 的进程作为父进程创建了 pid=5947 的子进程

p5947的父进程 应该是 5945 ,但是 这时 5945进程肯能已经死亡。 (具体原因自己还没有弄明白,如需深入学习可以见参考资料)

进程间通信: 管道及无名管道

一、无名管道(pipe)   1.1管道的介绍   A.管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道   B.只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);   C.单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。   D.数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。   1.2管道的创建   本文永久更新链接地址

相关内容

    暂无相关文章