【Linux学习笔记(九)】之进程操作,fork,exec函数族,wait,waitpid函数

本文章由公号【开发小鸽】发布!欢迎关注!!!


老规矩–妹妹镇楼:

一. fork函数

(一) 概述

        fork函数在一个进程的基础上创建一个新的子进程。

(二) 函数原型

pid_t fork(void);

(三) 函数返回值

        创建成功时,返回两次。父进程返回子进程的id,子进程返回0.。

(四) getpid

        获得当前进程的id(pid)。

pid_t getpid(void);

(五) getppid

        获得当前进程的父进程的id(ppid)。

pid_t getppid(void);

(六) 使用示例


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

int main(){
	printf(“Begin\n”);
	pid_t pid = fork();
	if(pid < 0){
		perror(“fork err”);
		exit(1);
	}
	//子进程
	if(pid == 0){
		printf(“I am a child, pid=%d, ppid=%d\n”, getpid(), getppid());
	}
	else if(pid > 0){
		printf(“childpid=%d, self=%d, ppid=%d\n”, pid, getpid(), getppid());
		sleep(1);
	}
	printf(“End … \n”);
	return 0;
}

二. 进程操作

(一) 查看进程信息

        init进程是所有进程的祖先。

ps aux
ps ajx 可以追溯进程之间的父子关系、

(二) 杀死进程

        kill -l 查看信号相关的信息

        给进程发送一个信号,杀死进程的信号为 SIGKILL 9号信号。

kill -SIGKILL pid
	pid为进程的id

三. 创建多个子进程

        上面已经讲解过了创建单个子进程,直接使用fork函数创建子进程即可。那么,在创建多个子进程时,如果直接使用for循环创建多个子进程就会出现子进程会接着循环创建自己的子进程,即如果循环5次,那么会创建32个子进程,而不是5个子进程。

        要想解决这个问题,就要在确认是新创建的子进程处通过break离开循环。

#include<stdio.h>
#Include<unisted.h>
#include<stdlib.h>

int main(){
	int n =5;
	int i = 0;
	pid_t pid = 0;
	for(I = 0; I < 5; ++i){
		pid = fork();
		if(pid == 0){
			printf(“I am child, pid=%d, ppid=%d\n”, getpid(), getppid());
			break;
		}
		else if(pid > 0){
			printf(“fater, pid=%d, ppid=%d\n”, getpid(), getppid());
		}
	}
	return 0;
}

四. exec函数族

(一) execlp函数

1. 用途

        借助PATH环境变量,加载一个进程。

2. 函数原型
int execlp(const char* file, const char * arg,);

3. 函数返回值

        成功不返回,失败返回-1

4. 函数参数

        file: 要加载的程序的名称,该函数需要配合PATH环境变量使用,在环境变量的目录中搜索有无参数1,通常用于调用系统程序,如:ls, cp…

        arg: 参数列表,参数列表最后需要一个NULL作为结尾

(二) execl函数

1. 用途

        通过路径 + 程序名 来加载一个进程。

2. 函数原型
int execl(const char * path, const char * arg,);

3. 函数返回值

        成功无返回,失败返回-1

4. 函数参数

        参数与execlp函数一样,只不过path要加上路径名。

如: 加载 ls 命令并带有 -l,-F 参数

execlp(“ls”, “ls”,-l”,-F”, NULL);

execlp函数在PATH的目录下搜索ls 程序名称

execl(/bin/ls”, “ls”,-l”,-F”, NULL);

execl函数在绝对路径中搜索ls 程序名称


五. 孤儿进程与僵尸进程

(一) 孤儿进程

        该进程的父进程被kill了,该进程被init进程给领养了。

(二) 僵尸进程

        子进程被kill了,父进程没有回收子进程的资源,则该子进程成为了僵尸进程。

        那么僵尸进程如何被回收呢?通过kill父进程,init进程领养子进程,init进程负责回收子进程。


六. wait函数

(一) 概述

        wait函数一般用于回收子进程的资源,如果子进程没有被Kill,则wait函数一直阻塞等待着子进程的死亡,并且能够知晓子进程的死亡原因。

(二) 作用

  1. 阻塞等待

  2. 回收子进程资源

  3. 查看死亡原因

(三) 函数原型

pid_t wait(int * status);

status: 传出参数

(四) 函数返回值

        成功返回 终止的子进程ID
        失败返回 -1

(五) 子进程死亡原因

1. 正常死亡 WIFEXITED

        如果WIFEXITED为真,则使用WEXITSTATUS得到退出状态

2. 非正常死亡 WIFSIGNALED

        如果WIFSIGNALED为真,则使用WTERMSIG得到信号


七. waitpid函数

(一) 概述

        回收子进程。

(二) 函数原型

pid_t waitpid(pid_t pid, int * status, int options);

(三) 函数参数

1. pid
<-1 传递的是组id
-1 回收任意
0  回收和调用进程组id相同组内的子进程
>0 回收指定的pid

2. options
0和wait相同,也会阻塞
设置WNOHANG,如果当前没有子进程退出,会立刻返回

(四) 函数返回值

        如果设置了WNOHANG,那么如果没有子进程退出,则返回0;如果有子进程退出,则返回退出的pid

        失败返回-1(没有子进程)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值