您的位置:首页 > 编程语言 > PHP开发

fork、getpid函数的进程小知识

2016-07-20 09:54 405 查看


getpid函数与fork函数都是与进程有关的函数。

 

getpid函数原型为: pid_t getpid(void);

函数返回值为当前进程的PID。吐槽一下《UNIX环境高级编程》的中文版翻译,将它翻译为“调用进程的进程ID”,很容易让人误解成是当前进程的父进程ID。仔细阅读getpid的man手册,介绍getpid功能时,就一句:“get process identification”,而下面的详解中提到返回值是“returns the process ID of the calling process”。简单地将“the calling process”翻译成“调用进程”,似乎不太好。

 

fork函数原型为: pid_t fork(void);

函数返回值有三种情况:

                在子进程中返回0

              在父进程中返回子进程ID,一般大于0。

                出错时返回-1

意思很明确,尽管如此,却还是有几个地方容易让人误解。

第一:子进程与父进程共享哪些数据?哪些程序?

这里有一个很简单的例子,比如在fork之前的printf语句,会不会被子进程打印?答案是不会,因为该语句已被执行。而在fork之前的数据,却会复制到子进程中。

第二:子进程难道与父进程完全一样吗?

 在没有执行exec之前,确实是一样的,只不过fork在父子进程中的返回值是不一样的。可以通过这个特性使用if语句改变程序执行顺序。

第三:子进程的父进程消失以后,子进程归谁管?

由一个进程号为1的家伙代管,据说这家伙叫init进程,非常博爱,是所有孤儿进程的父进程,所谓孤儿进程,就是找不到产生自己的父进程的子进程。有些乱,但真相就是这样的。

以一个代码示例来说明:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(){
pid_t tmp5;
       pid_t tmp;

tmp5=getpid();
printf("parent pid %d\n",tmp5);   /* 返回当前进程的进程ID */

pid_t tmp4=getppid();
printf("%d's parent pid is %d\n",tmp,tmp4); /* 返回调用当前进程的进程ID */

tmp=fork();

if(tmp < 0){
printf("error happans in fork\n");
exit(1);
}
else if(0== tmp){ /* 子进程 fork 返回值为0 */

printf("\n\n");
printf("tmp == %d\n, is child process\n",tmp);

pid_t tmp1=getpid();
printf("child id is: %d\n",tmp1);

pid_t tmp2=getppid();
printf("%d's parent id is: %d\n",tmp1,tmp2);   /*  getppid的返回值tmp2可能为1,或者tmp3,取决于进程调度 */
}else{  /* 父进程fork 返回值为子进程id */
printf("\n\n");
printf("tmp == %d\n, tmp is child pid\n",tmp);
pid_t tmp3=getpid();
printf("parent pid  is %d\n",tmp3);   /* 获取当前进程id,应该与程序最早打印的进程id 值相同  */
sleep(10);          /* 假设没有sleep(10)这一句,父进程立即执行完毕后消失,而子进程可能后于它消失,成为孤儿进程 */
}

return 0;
}


一个运行结果:

parent pid 18302

32767's parent pid is 17881

tmp == 18303

, tmp is child pid

parent pid  is 18302

tmp == 0

, is child process

child id is: 18303

18303's parent id is: 18302
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: