进程
基本概念
什么是进程:
进程是程序的一次执行过程,进程是程序执行和资源管理的最小单元
。在Linux环境下,每个正在运行的程序都被称为进程
并行与并发:
- 并行(微观上,一个很短时间范围内):在很短的时间段内(时间点上),两个事情同时发生
- 并发(宏观上,一个时间段内):在一段时间内,多个事情同时发生(实际上多个事情有先后顺序)
- 服务器并发访问,应用程序并发执行
什么是进程控制块(PCB):
进程是Linux系统中调度和管理资源的单位,系统通过进程控制块来描述和表示一个进程的变化
进程控制块包括的内容:
进程的描述信息(进程ID,进程状态…)
进程控制信息(调度信息,时间片,优先级…)
进程的资源信息(内存资源,打开的文件,使用的定时器…)
Linux系统中进程控制块中的每一项都是通过
task_struct
结构体来表示,定义在#include <linux/sched.h>
头文件中
进程控制称为PCB,它是一个复杂的数据结构,在管理一系列的结构体和结构体成员指针指向的内存空间;
一个进程在执行时处于不同的状态:创建—就绪—运行—阻塞—销毁
进程的特征:
- 并发性:多个进程可以在同一时间运行在一个内存空间中,任何进程都可以同其他进程并发执行
- 动态性:进程在不同状态间不断的切换(非静态)
- 独立性:进程之间默认是独立运行的,互不相干
- 异步性:进程间运行时,按照不同的速度和时间在运行,在微观层面不是同时的,甚至是制约的,不可预知的顺序执行
进程的基本操作
fork
调用头文件
#include <unistd.h>
函数原型
pid_t fork(void);
功能
创建子进程
无参数
返回值
fork函数调用一次,返回两次。父进程中,fork返回新创建的子进程的PID;子进程中,fork返回0;出错时,返回-1,提供错误码,可以使用perror。
vfork
调用头文件
#include <unistd.h>
#include <sys/types.h>
函数原型
pid_t vfork(void);
功能
创建子进程
无参数
返回值
vfork函数调用一次,返回两次。父进程中,vfork返回新创建的子进程的PID;子进程中,vfork返回0;出错时,返回-1,提供错误码,可以使用perror。
fork
和vfork
都能创建进程他们的区别:
fork创建的子进程拷贝了父进程的所有虚拟内存(栈、堆、代码段、数据段);父子进程执行先后顺序不确定,结束的先后顺序也不确定
vfork创建的子进程共享了堆栈空间;子进程先执行先结束,父进程在子进程结束后才执行,父进程后结束
子进程先结束,就会清理共享的堆栈空间,导致父进程无法在访问堆栈中的数据,程序会报"核心已转储"的错误
解决方法:在子进程代码最后调用_exit函数,该函数会终止当前进程并且不会清理 堆栈空间,从而不会报错
exit与_exit
调用头文件
#include <unistd.h>
#include <stdlib.h>
函数原型
void exit(int status);
void _exit(int status);
功能
退出,或终止进程
参数
-
status:退出码/退出的状态值
EXIT_FAILURE 1
EXIT_SUCCESS 0
返回值(无)
exit
和_exit
都能退出进程他们的区别:
_exit
会直接终止进程
特性 | exit | _exit |
---|---|---|
清理函数执行 | 是 | 否 |
标准IO缓冲区刷新 | 是 | 否 |
释放标准库资源 | 是 | 否 |
使用场景 | 正常程序退出 | 子进程或紧急退出 |
标准库依赖性 | 依赖标准库 | 不依赖标准库 |
getpid与getppid
调用头文件
#include <unistd.h>
#include <sys/types.h>
函数原型
pid_t getpid(void);
pid_t getppid(void);
功能
getpid
:获取当前进程ID
getppid
:获取当前进程父进程ID
参数(无)
返回值
getpid
:返回当前进程
getppid
:返回当前进程父进程ID
wait与waitpid
调用头文件
#include <sys/types.h>
#include <wait.h>
函数原型
pid_t wait(int *status);
pid_t waitpid(pit_t pid, int *status,int options);
功能
wait
:阻塞父进程,直到某个子进程退出
waitpid
:阻塞调用程序,直到编号为pid的子程序退出
参数
-
status:获取到的子进程结束状态值,获取到status后用
WEXITSTATUS(status)
来转换子进程退出时的退出码 -
pid:等待的子进程ID
-
options:附加选项(一般填0)
WEXITED
/Wait for children that have terminated.WSTOPPED
/Wait for children that have been stopped by delivery of a signal.WCONTINUED
/Wait for (previously stopped) children that have been resumed by delivery of SIGCONT.The following flags may additionally be ORed in options:
WNOHANG
/As for waitpid().
WNOWAIT
/Leave the child in a waitable state; a later wait call can be used to again retrieve the child status information.
返回值
成功返回退出子程序的ID,错误返回**-1**
exec族函数
exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容(在调用进程内部执行一个可执行文件。)
一个进程调用exec族函数后,代码段,数据段,堆段,栈段的都会被新程序覆盖,保留PID(进程号)
exec函数族调用的头文件都是以下:
#include <unistd.h>
execl
函数原型
int execl(const char *path,const char *arg,...);
int execlp(const char *file,const char *arg,...);
int execle(const char *path,const char *arg,...);
功能
用path或者file指定的进程地址空间替换调用进程的地址空间
参数
- path:执行程序的全路径
- file:执行程序的名称
- arg,…:被执行程序所需的命令行参数,含程序名。以空指针结束
返回值
错误时返回-1,提供错误码,可以使用perror**(只有错误才返回)**
execv
函数原型
int execv(const char *path,char *const argv[]);
int execvp(const char *flie,char *const argv[]);
int execve(const char *path,char *const argv[],char *const envp[]);
功能
用path或者file所指定的进程地址空间替换调用进程的地址空间
参数
- path:执行程序的全路径
- file:执行程序的名称
- argv:被执行程序所需的命令行参数,含程序名。以空指针结束
- envp:指向环境参数的数组
返回值
错误时返回-1,提供错误码,可以使用perror**(只有错误才返回)**
system
调用头文件
#include <stdlib.h>
函数原型
int system(const char *command);
功能
相当于命令行运行command指令
参数
- command:想要在命令行实现的指令字符串
返回值
- command为NULL,如果shell存在返回非零值,如果不存在返回0;
- 出错返回-1;
- 成功返回终端状态
标签:fork,const,exec,int,char,exit,进程,include From: https://blog.csdn.net/Are_pro_bald/article/details/145227927system("./abc &");
&
在system中表示后台运行abc这个程序想要杀死后台的程序,需要使用
killall "进程名称" 或者 kill -9 "进程号"
不能使用
ctrl+c
(只能终止前台进程)要获取进程号,可以使用
ps -aux | grep "进程名称"