Linux — 进程控制

进程创建

fork()函数

使用fork系统调用通过复制调用进程来创建一个新进程,调用fork的进程我们称为父进程,创建出来的新进程称之为子进程。

pid_t fork(void);
fork的返回值

对于父进程来说,返回值是子进程的进程pid。
对于子进程来说,返回值是0。
父子进程创建后,子进程复制了父进程的PCB中的大部分数据,因为父子进程是以父进程为模板来创建的,因此父子进程的代码段是完全一样的,也就是说,子进程运行与父进程相同的程序,直到用户做出判断后,父进程进行父进程的操作,子进程进行子进程的操作,相对独立,操作结束后若均未退出的话则运行剩下相同的程序。

vfork函数

创建一个子进程(fock使用写时拷贝技术后,vfock就被淘汰了)

pid_t vfork(void);
vfork函数的特性
  1. 子进程没有(退出)或者运行其他程序,父进程是阻塞的(因为vfork创建子进程后,父子进程是共用一块虚拟地址空间,那么他们共用一个栈区,有可能回造成调用栈混乱),也就意味着子进程是优先运行的(因为创建出子进程大多时候都是为了让他运行其他程序),子进程退出(不能在main函数中return)之后,父进程才能运行
  2. vfork设计出来的目的就是为了创建一个子进程,然后直接运行其他的程序。重新运行其他的程序就是重新给子进程开辟新的空间,更新他自己的一份虚拟地址空间和页表
  3. 子进程先运行,等到子进程exit退出或者程序替换之后,父进程才开始运行,子进程如果使用return退出,会造成调用栈混乱,导致父进程陷入死循环(centOS环境)

进程终止

终止方式

  • main函数中return退出
  • exit 库函数
  • _exit 系统调用接口

exit与_exit的区别
exit是温和性的退出,在退出前会温和的释放资源,刷新缓冲区
_exit是暴力退出,直接释放资源退出,不会刷新缓冲区

杀死进程

kill

  • kill-l 查看信号
  • kill pid
  • kill -9 强制杀死进程
  • kill -进程组id 杀死一组进程

进程等待

wait函数

pid_t wait(int *status)

//函数功能
//阻塞等待子进程退出,回收子进程残留资源 ,获取子进程结束状态(退出原因)。

//头文件
#include<sys/tyoes.h>
#include<sys/whit>

//参数
status    输出型参数,获取子进程退出状态(退出状态码),可设置成为NULL(不关心退出状态)
返回值
	成功返回子进程的pid
	失败返回-1

waitpid函数

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

//waitpid是一个阻塞/非阻塞可选的函数

//参数
pid
    -1    //等待任意一个子进程
    >0    //等待指定子进程
status    //获取退出状态码
options    
    0    //阻塞
    WNOHANG    //非阻塞
返回值    
    -1    //出错
    0    //没有子进程退出(设置成非阻塞的情况下)
    >0    //退出的子进程pid

子进程的退出状态码

在这里插入图片描述

//退出状态码的一些操作
WIFEXITED(status)    //判断是否正常退出
WEXITSTATUS(status)    //获取status中的子进程退出码

进程替换

替换原理

创建子进程后,子进程往往要调用一种exec函数以执行另一个程序,当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程(调用main函数的函数)开始执行(替换的是程序所运行的代码,将另一端程序加载到内存中,通过页表将原先的进程的映射关系,重新建立在新程序在内存给中的地址,相当于替换了进程所运行的程序以及所要处理的数据,因此,可以这样认为,替换了代码段,重新初始化数据段)。

exec函数族

//exec函数族中的函数只有在失败时才会返回-1
//即程序在调用成功时会直接执行调用程序结束,只有在调用失败时才会返回继续执行原程序

//函数族功能:替换当前的程序

//01
int execl(const char *path, const char *arg, ...);
//path    源程序(替换的文件)的文件路径名
//arg    参数,通常为可执行程序名
//NULL    结束标志

//02、
int execl("/bin/ls", "ls", "-l", NULL);    //不定参数列表需要NULL结尾

//03、
int execlp(const char *file, const char *arg, ...);
//file     文件名称,必须再指定路径下,若没有,则需要自己添加路径
int execlp("ls", "ls", "-l", NULL);

//04、
int execle(const char *path, const char *arg, ..., char *const envp[]);
//envp    //环境变量, 字符串指针数组
//需要引入环境变量表
char *env[] = {"MYVAL = 10", NULL};    //注意以NULL结尾
int execle("./test", "test", "-a", NULL, env);

//05、
int execv(const char *path, char const argv[]);
char *arg[] = {"ls", "-a", NULL};
int execl("/bin/ls", arg);

//06、
int execvp(const char *file, char const argv[]);

//07、
int execve(const char *path, char const argv[], char *const envp[]);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值