进程的含义:
进程是一个程序执行的过程。
进程运行所需要的资源
cpu调用, 内存资源。 文件系统,网络,输入输出设备。
系统管理进程,通过PCB块(process control block,进程控制块)
PCB内存在的主要成员
1.PID:进程标识符
2.chdir:当前工作路径
3.umak:0002
4.信号相关设置处理异步io,用户id,组id
并发与并行的区别
1.并发,在同一时刻,多个任务同时进行。 单cpu场景。 cpu会被多个任务调度。
2.并行, 在同一时刻,多个任务同时进行。 多cpu场景。
常用调度算法
1.段任务优先
2.先来先服务
3.时间片轮询
4.完全公平调度算法(linux多级队列)
linux中查询进程的命令
ps aux:查看系统上所有进程的相关信息。
pid, stat ,comm; top:会自动刷新,类似 windons 任务管理器
kill,killall:给某个进程发送信号。大多数信号都是关闭进程。pstree:查看进程相互之间的父子关系。
注意:kill本质不是杀死进程,而是发送信号,不同的信号有不同的效果
进程创建函数
pid_t fork( )
1.子进程复制父进程的0到3g空间和父进程内核中的PCB,但id号不同。
2.功能:通过该函数可以从当前进程中克隆一个同名新进程。
3.克隆的进程称为子进程,原有的进程称为 父进程。
4.子进程是父进程的完全拷贝。
5.子进程的执行过程是从fork函数之后执行。
一次调用会传回来两个值
1.一个是父进程(返回值大于0)
2.一个是子进程(返回值小于0)
注意:子进程和父进程的顺序并不确定,哪个先运行都是正常现象
父进程和子进程的变量不共享
getpid和getpidd运用
1.getpid获取当前pid号
2.getppid可以获取父进程的pid号
代码示例:
写时复制
在fork中, 先复制pcb 给子进程。 在子进程的pcb块中。pid和父进程的pid是不一样。fork完后,子进程的用户空间和父进程是共享状态。 当父进程或子进程对数据进行修改,这是子进程在必须开辟出对应的内存空间。
进程退出的8种情况
1.main 中return
2.exit(), c库函数,会执行io库的清理工作,关闭所有 的流,以及所有打开的文件。已经清理函数(atexit)。
3._exit,_Exit会关闭所有的已经打开的文件,不执行清理函数。
主线程退出
5.主线程调用pthread_exit
异常终止
6.abort()
7.signal kill pid
8.最后一个线程被pthread_cancle
进程退出后的状态
孤儿进程: 父进程先消亡,子进程存在。子进程被称为孤儿进程。会重新找到父进程。 不需要过多关注。
僵尸进程:子进程先消亡。用户空间会被释放,不会在被调度。但是,对应的pcb块没有被回收。依然占据了内核内存的空间。
可以通过top查询linux系统目前是否存在僵尸进程
注意: 父进程需要对僵尸进程进行回收。
连续fork之后的情况
fork 之后,父、子是独立进程,默认谁先被 CPU 调度是不确定的(异步、竞争),很多情况下父进程优先拿到 CPU 先执行,跑得更快。
如果父进程很快执行完、直接退出,子进程还没抢到时间片,就来不及打印输出,甚至输出混在 shell 提示符后面看不见。
我们可以在父进程里加 sleep(),主动让父进程暂缓,给子进程留出时间去执行、打印
没加sleep()前,子进程来不及输出
加上sleep()后