目录
重点:进程概念,fork函数
字符串分割函数strtok
查询进程相关命令
1.ps aux
查看进程相关信息
1.就绪态、运行态 R
2.睡眠态、等待态
可唤醒等待态 S
不可唤醒等待态 D
3.停止态 T
4.僵尸态 Z
5.结束态
2.top
根据CPU占用率查看进程相关信息
3.kill -2 进程pid //
发送信号 进程名对应的所有进程
killall a.out
fork函数
无需传参,调用就会产生一个父进程一个子进程,其实是复制了一份代码,同时在运行两份代码。
getpid拿自己的进程号
getppid拿父进程号
fork()&&fork()||fork()
几个进程? 五个 看最后一层有多少个进程
分析:fork()它返回值有两种情况,大于0,等于0,&&如果左边为1,右边执行,如果为0,右边不执行,|| 如果左边为1,右边不执行,如果左边为0,右边执行,按照这个思想去分析。
父子进程的关系:
子进程是父进程的副本。子进程获得父进程数据段,堆,栈,正文段共享。
在fork之后,一般情况那个会先运行,是不确定的。如果非要确定那个要先运行,需要IPC机制。
区别:
1)fork的返回值
2)pid不同
进程的终止:8中情况
1)main 中return
2)exit(), c库函数,会执行io库的清理工作,关闭所有 的流,以及所有打开的文件。已经清理函数(atexit)。
3)_exit,_Exit 会关闭所有的已经打开的文件,不执行清理函数。
4) 主线程退出
5)主线程调用pthread_exit
异常终止
6)abort()
7)signal kill pid
8)最后一个线程被pthread_cancle
僵尸进程,孤儿进程
2.进程的退出
僵尸进程和孤儿进程
僵尸进程:进程执行结束但空间未被回收变成僵尸进程
僵尸进程:子先消亡
孤儿进程:父先消亡
一个程序结束,命令提示符就输出,子进程还没结束,僵尸进程没有这种情况是因为将pcb块和子进程一起结束才程序结束,所有没有一个先一个后。
进程的退出
void exit(int status)
exit(0/1);
功能:
让进程退出,并刷新缓存区
参数:
status:进程退出的状态
返回值:
缺省
EXIT_SUCCESS 0
EXIT_FAILURE 1
exit(0/1)结束函数进程
void _exit(int status)
2._exit 系统调用
void _exit(int status);
功能:
让进程退出,不刷新缓存区
参数:
status:进程退出状态
返回值:
缺省
重点区别:
exit()和_exit()主要区别是结束进程时会不会刷新缓冲区。
在下面可以看到不会i打印出aaaaaaa出来,程序到达exit就结束,其中exit()函数成功写入1.txt,而_exit()写入1.txt失败,主要是其不会刷新缓冲区。
回调函数
atexit函数
int atexit(void (*function)(void));//函数指针
功能:
注册进程退出前执行的函数
参数:
function:函数指针
指向void返回值void参数的函数指针
返回值:
成功返回0
失败返回非0
当程序调用exit或者由main函数执行return时,所有用atexit
注册的退出函数,将会由注册时顺序倒序被调用
重点理解:程序快要结束时,才会调用atexit函数