您的位置:首页 > 运维架构 > Linux

Linux进程入门学习(三)-进程创建等待

2017-08-12 16:36 399 查看

1. 进程的创建

fork 函数用于创建子进程

头文件
#include <unistd.h>


函数原型
pid_t fork(void);


返回值

失败:-1
成功:0 或者大于0 的正整数
等于0:新的子进程返回值
大于0:父进程中返回值大于0,该大于0 的值是子进程的PID


分析:

子进程相当是父进程的一个复制品,将父进程整个内存空间、包括栈、堆、数据段代码
段等等
父子进程有部分属性不一致:PID 记录锁挂起的信号
父子进程运行顺序是不确定,有时可能是父进程先运行,也有可能是子进程先运行


示例:利用fork 创建子进程

/***********************************************************************
* File Name: m_fork.c
* Author: 谢保成
* E-mail: 2446603068@qq.com
* Create Time: Mon 07 Aug 2017 02:12:36 AM PDT
***********************************************************************/

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

int main()
{
pid_t pd;
int i=10;
printf("test for fork.\n");

pd = fork();
if(pd == -1)
{
printf("fork child PID fail.\n");
}
//子进程
else if(pd == 0)
{
printf("child pd = %d\n", pd);
printf("child process.\n");
i = 30;
printf("child i = %d\n", i);
while(1);
}
//父进程
else if(pd > 0)
{
sleep(1);

printf("parent pd = %d\n", pd);
printf("parent process.\n");
printf("parent i = %d\n", i);
while(1);
}

return 0;
}


getpid 函数用于获取进程PID

头文件
#include <unistd.h>


函数原型
pid_t getpid(void);


返回值 成功,返回进程ID

getppid 函数用于获取父进程PID

头文件
#include <unistd.h>


函数原型
pid_t getppid(void);


返回值 父进程ID

示例:利用getpid 及getppid 函数打印进程的PID 及父进程PID

/*******************************************************************************
* File Name: t_fork.c
* Author: 谢保成
* E-mail: 2446603068@qq.com
* Create Time: Mon 07 Aug 2017 02:38:44 AM PDT
********************************************************************************/
4000

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

int main()
{
pid_t pd;
int i=10;
pd = fork();
if(pd == -1)
{
perror("create failure!\n");
return -1;
}
//子进程
if(pd == 0)
{
printf("child pd = %d\n", pd);
printf("child process\n");
//打印自己的PID及父进程的PID
printf("child process  mypid = %d, myparentpid = %d\n", getpid(), getppid());
while(1);
}
//父进程
if(pd>0)
{
//睡眠1s,确保子进程先运行
sleep(1);
printf("parent pd = %d",pd);
printf("parent process\n");

//打印自己的PID 及父进程的PID
printf("parent process  mylist = %d, my parent PID = %d \n", getpid(), getppid());
}
return 0;
}


2. 进程的等待

孤儿进程

父进程生成子进程,但是父进程比子进程先结束;子进程会变成孤儿进程,由系统1号init 进程进行接管。init 进程接管后,在该孤儿进程结束的时候,负责“收尸”,回收系统资源及进程信息。


僵尸进程

子进程已经退出,但是没有父进程回收它的资源(父进程生成的子进程,但是子进程比父进程先挂掉,如果父进程没有收回它的资源时,那么子进程挂掉后就变成了僵尸进程;应该尽量避免产生僵尸进程,可以在父进程调用wait 或者waitpid 进程回收)


wait 函数用于等待子进程

功能描述

进程一旦调用了wait,就立即阻塞自己,由wait 自动分析是否当前进程的某个子进程已经退出。如果让它找到了这样一个已经变成僵尸的子进程,wait 就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait 就会一直阻塞在这里,直到有一个出现为止。


头文件
#include <sys/wait.h>


函数原型
pid_t wait(int *stat_loc);


返回值

成功:被成功回收资源的子进程PID
失败:-1


参数

int *stat_loc:返回状态


示例:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
pid_t pd;
int i = 10;
//创建子进程
pd = fork();
if(pd == -1)
{
perror("creat failure!\n");
return -1;
}
//子进程
if(pd == 0)
{
printf("child pd = %d\n",pd);
printf("child process\n");
//打印自己的PID 及父进程的PID
printf("child process mypid = %d, myparentpid = %d\n",getpid(),getppid());
}
//父进程
if(pd > 0)
{
pid_t return_pid;
int stat_loc;
//睡眠1s,确保子进程先运行
printf("parent pd = %d\n",pd);
printf("parent process\n");
//打印自己的PID 及父进程的PID
printf("parent process mypid = %d, myparentpid = %d\n",getpid(),getppid());
//等待子进程退出并回收它的资源
return_pid = wait(&stat_loc);
printf("return_pid = %d\n",return_pid);
}
return 0;
}


waitpid 函数用于等待子进程

头文件
#include <sys/wait.h>


函数原型
pid_t waitpid(pid_t pid, int *stat_loc, int options);


参数

pid_t pid:指定等待的子进程PID
<-1:等待组ID 为pid 绝对值的进程组内的任意子进程
-1 :等待任意子进程
=0 :进程组内的任意子进程
>0 :等待PID 为pid 的子进程
int *stat_loc:返回状态int options:
WNOHANG:当没有已退子进程时立即返回,即非阻塞
WUNTRACED:当有子进被暂停立即返回
WCONTINUED:当有子进程收到信号立即返回
若写0,就是阻塞,相当wait(int *stat_loc);返回状态可以通过宏来


返回值

-1:执行失败
0:指定了选项WNOHANG,且没有已退子进程
>0:成功回收了PID 等于返回值子进程的资源


实例

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
pid_t pd;
int i = 10;
//创建子进程
pd = fork();
if(pd == -1)
{
perror("fork failure!\n");
return -1;
}
//子进程
if(pd == 0)
{
printf("child pid = %d\n",pd);
//打印自己的PID 及父进程的PID
printf("child:PID=%d, PPID=%d\n",getpid(),getppid());
}
//父进程
if(pd > 0)
{
pid_t return_pid;
int stat_loc;
printf("parent pid = %d\n",pd);
//打印自己的PID 及父进程的PID
printf("parent:PID=%d, PPID=%d\n",getpid(),getppid());
//非阻塞不等待子进程退出
return_pid = waitpid(pd, &stat_loc, WNOHANG);
printf("return_pid = %d\n",return_pid);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  fork linux getpid getppid wait