一、进程分类
交互进程:由shell控制和运行的,和终端关联的。交互进程可以在前台运行,也可以在后台运行。
前台进程:占有终端的进程,其他的称之为后台进程
后台进程:不占用终端的进程
守护进程:在后台运行,他一般是linux启动时执行,系统关闭才结束,批处理进程:不属于某个终端,他被提交到一个队列中以便顺序执
孤儿进程:父进程产生了子进程,但父进程结束,子进程未结束的情况,这种进程会移交给init进程,init进程会成为孤儿进程的父进程。
前后台进程转换:
ctrl+c: 终止进程 结束进程 回到shell
ctrl+z:挂起,把前台进程转换成后台进程,回到shell ,进程没结束
jobs : 查看当前在后台执行的进程的进程pid (命令 jobs -l)
fg +n: 其中的n是jobs的序列号 不是pid的值,在后台暂停,程序没结束。(fg 1)
& :在可执行程序后加去地址符号,则进程默认转换成后台进程(./a.out &) 和当前终端没关系 没法用ctrl+c 和ctrl+z 来结束和挂起(需要补充)
bg N: 将前台进程转换成后台进程运行。 (bg n)
二、进程状态
新建状态:应用程序被创建时的状态,没有进入到就绪队列中。
就绪状态:进行已经具备运行条件,等待系统分配处理器运行(放入到就绪队列中)
运行状态:进程正在运行
阻塞状态:又称之为等待状态或者睡眠状态。进程在等待一个信号或者系统资源
停止:也叫死亡状态,进程完成任务后正常结束。
进程的三要素:
每个进程都有进程id,是唯一的标志
每个进程都有pcb,内核中秒数进程的主要数据 一个结构体
每个进程都会进行内存映射。
三、进程的命令
ps: 列出活跃的进程
ps -au 列出所有进程 但进程都和终端有关系
ps -aux 列出所有进程,包括有关系和终端没关系的进程。
top 动态显示进程信息,等价于任务栏管理器
top -d n秒 每隔n秒刷新一次信息。
pstree 打印进程的树状信息,关系信息。
ps -ef 标准的格式显示系统的进程信息
kill 发送信号给进程
列出所有信号 kill -l
给进程发信号 kill -信号 PID
1) SIGHUP 终端关闭会发送 进程结束
2) SIGINT ctrl + c 终止当前进程 进程结束
3) SIGQUIT ctrl + \ 停止当前进程 进程结束
9) SIGKILL 杀死进程 进程结束
12) SIGUSR2 用户自定信号
14) SIGALRM 闹钟信号
19) SIGSTOP 进程暂停
20) SIGTSTP ctrl+z 挂起进程 转换成后台进程
四、进程的API函数
1.获取进程ID
函数原型 pid_t getpid(void);
头文件: #include <sys/types.h> #include <unistd.h>
返回值: 当前进程的进程id号
函数原型:pid_t getppid(void);
作用: 获取当前进程的父进程id号
2.创建子进程 (fork和vfork的区别)
2.1 fork( ),函数原型pid_t fork(void);创建子进程,克隆了父进程的一切特征(也克隆了父进程的内存空间)父子进程之间不受影响,父进程改变某一个变量,子进程不改变。返回值有2个,返回给父进程的是子进程的PID,返回给子进程的是0,如果失败返回-1;
2.2 vfork( ) 换上原型 pid_t vfork(void);用来创建子进程,也是返回两个值,父进程是返回子进程的pid 子进程返回0,但是子进程不会赋值父进程的内存空间,是以共享的方式访问父进程的内存,如果父进程的内存修改,子进程同时修改。vfok中是优先子进程执行,子进程结束后再执行父进程。
2.3 clone( ) 是linux内核创建进程的方式,创建进程和线程都使用的clone函数,开发中尽量避免使用,因为不利于移植。
列如: 父子进程执行不同的代码
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
printf("CSDN帅\n");
pid_t pd = fork();
//子进程执行pid == 0中的代码
if(pd == 0)
{
while (1)
{
printf("我是子进程\n");
}
//父进程执行else中的代码
else
{ while (1)
printf("----我是父进程--------\n");
printf("pid = %d\n",pd);
printf("好帅\n");
//从fork开始的代码,在父进程和子进程中都有一份
}
return 0;
}
写操作拷贝技术:fork创建新进程,但不会产生父进程的副本。当子进程需要修改父进程内容的时候,才会拷贝需要修改的内存空间。父进程同样。
用vfork创建一个子进程,公用变量x 父子进程分别打印。