1>什么是进程?
是程序的一次动态执行过程
是资源管理的最小单位
是一个独立可调度的任务
2>进程的特点
独立性: 各个进程之间,互不干扰 -- 都有自己的执行空间
并发性: 宏观同时,微观异步
动态性: 程序的执行过程
异步性: 每一个进程执行的速度都由CPU调度
信号:
是一种异步通知由内核发起
kill命令-->发送信号 默认功能为结束进程
kill函数-->发送信号 没有默认功能,必须指定信号
kill -l 查看kill的信号
信号详解:
1->SIGHUP:终端关闭时,给其他所有的进程发送信号
2->SIGINT:结束进程 ctrl+c
3->SIGQUIT:结束进程 ctrl + \
9->SIGKILL: 强制杀死进程 不能被注册,不能被阻塞,不能被忽略
10->SIGUSR1:系统给用户留的自用信号 ---signal
12->SIGUSR2:系统给用户留的自用信号 ---signal
14->SIGALRM:计时器,闹钟信号,当闹钟倒计时到0秒,触发信号,结束进程
17->SIGCHLD:子进程结束时给父进程发送的信号
18)SIGCONT:继续进程
19)SIGSTOP:暂停进程 不能被注册,不能被阻塞,不能被忽略
20)SIGTSTP:暂停进程
用法: kill -信号 pid
拓展API: getpid getppid 头文件:#include<sys/types.h> <unistd.h>
pid_t getpid(void)//获得当前进程的PID号 pid_t getppid(void)//获得当前进程的父进程的PID号
进程API:进程的 生 / 老 / 病 / 死 / 收尸 / 不想死 ----守护进程
进程的生: 创建子进程
#include <sys/types.h> #include <unistd.h>
pid_t fork(void);
成功父进程返回子进程的PID号 失败返回-1,并设置错误码
进程的替换: exec函数族
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...
/* (char *) NULL */);
int execlp(const char *file, const char *arg, ...
/* (char *) NULL */);
int execle(const char *path, const char *arg, ...
/*, (char *) NULL, char * const envp[] */);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
特点:1->都是exec开头
2->带l:参数以列表的方式传递
3->带v:参数以数组的方式传递
4->带p:需要去环境变量中寻找 默认去/bin或/usr/bin 去找
5->带e:有新的数据需要传递到另外一方
解析:第一个参数:找到这个命令/文件 第二个:执行这个命令的语句,以NULL结尾
返回值:EXEC只有出错时才返回,返回-1,并设置错误码
进程阻塞-->进程互斥
进程的上锁 --- 用来保护临界资源
flock 头文件:#include <sys/file.h>
int flock(int fd,int operation) 功能:给文件上锁
参数:fd:文件描述符 operation:锁的属性
LOCK_SH: 共享锁
LOCK_EX: 互斥锁
LOCK_UN: 解锁
LOCK_NB: 不上锁
返回值:成功返回0,失败返回-1,并设置错误码
进程的死:
方式:
老死---->程序运行完毕 main函数遇到return
被杀---->kill -9
自杀---->感觉自己没用 exit
exit _exit return
#include<stdlib.h>
void exit(int status); 功能:结束进程
参数:status:进程结束的状态
exit(1); exit(-1); exit(0?2?3);
进程结束是给系统返回的结束状态
是否收尸?
收尸时有用:可以获取进程退出的状态,并通过状态获取进程死法
不收尸没用:用来给代码编写者进行标识,一般标识为 -1代表进程错误退出 1代表进程正常退出
_exit
#include <unistd.h>
void _exit(int status); 功能:结束进程
参数:status:进程的退出状态
exit和_exit的区别: exit在结束进程的时候会刷新缓冲区 _exit结束进程不会做任何操作
return--->关键字,结束函数,可以通过结束main函数来达到结束进程的效果
收尸
进程资源回收
限制:只能父进程给子进程收尸
wait 头文件:#include <sys/types.h> <sys/wait.h>
pid_t wait(int *wstatus);
功能:父进程给子进程收尸 阻塞等待子进程死亡后收尸
参数: wstatus:子进程死亡状态 死亡信息,遗言-->保存在次低位字节上
返回值:成功收尸:返回收到的尸的子进程PID号 失败返回-1,并设置错误码
wait 无法直接指定收尸 只能通过操作子进程死亡顺序来改变收尸顺序
waitpid --->wait 的升级
#include <sys/types.h> <sys/wait.h>;
pid_t waitpid(pid_t pid,int *wstatus,int options);
功能:指定收尸 父进程给子进程收尸 阻塞等待子进程死亡后收尸
参数:
pid: >0 --- 给特定子进程收尸 waitpid(2304,...,...);
=0 --- 给当前父进程同组的所有子进程收尸
=-1 --- 给任意子进程收尸,无论在哪
<-1 --- 给进程组ID号为|PID|下的子进程收尸以组为单位
wstatus:子进程死亡状态
options:属性选择
0:阻塞等待收尸
WNOHANG:不阻塞
WUNTRACED:死因调查
WIFEXITED(wstatus):判断子进程是否正常死亡 --- 死亡报告
WEXITSTATUS(wstatus)----验尸
WIFSIGNALED(wstatus):判断子进程是否被信号杀死 --- 死亡报告
WTERMSIG(wstatus) ---验尸
WIFSTOPPED(wstatus):判断子进程是否因为信号传递而被停止 ---死亡报告
WSTOPSIG(wstatus) ---验尸
返回值:成功收尸返回收到尸的子进程PID号
非阻塞状态下:收到尸子进程的PID号,没用收到返回0
失败返回-1,并设置错误码
进程组操作
获取进程组组号
getpgid 头文件:#include <sys/types.h> <unistd.h>
pid_t getpgid(pid_t pid);功能:获取某个进程的进程组号
参数:PID:需要获取组号的PID进程号
返回值:成功返回进程组组号,失败返回-1,并设置错误码
设置某进程的组号
setpgid 头文件:#include <sys/types.h> <unistd.h>
int setpgid(pid_t pid, pid_t pgid); 功能:设置某进程的组号
参数:PID:要作用的进程 pgid:设置组号为多少
返回值:成功返回0,失败返回-1,并设置错误码
setpgid(2304,110);