今天我们继承学习进程,首先送给各人一句话:
如果痛恨所处的黑暗,请你成为你想要的光。 —— 顾城
1 认识进程收尾
进程的路径是可以改变的, 每个进程在启动的时候,会记录自己当前在哪个路径下启动。
我们可以使用fopen ("log.txt",“w”)来进利用用,该函数会在路径下创建一个新文件log.txt。即可验证进程所处路径:
- 1 #include<stdio.h>
- 2
- 3 int main(){
- 4 FILE* fp = fopen("log.txt","w");
- 5 (void)fp;//防止报错
- 6
- 7 return 0;
- 8 }
复制代码 我们编译运行之后,就可以发现当前路径下创建了一个新文件log.txt。
那我们可不可以改变一下进程的路径呢,固然可以,使用int chdir(const char* path)就可以实现改变进程路径的功能.
我们来试一试,通用通过代码来测试一下:
- 1 #include<stdio.h>
- 2 #include<unistd.h>
- 3 #include<sys/types.h>
- 4
- 5 int main(){
- 6
- 7 chdir("/home/jlx/lesson12");
- 8
- 9 FILE* fp = fopen("log.txt","w");
- 10 (void)fp;
- 11
- 12 while(1){
- 13 printf("I am a process,pid: %d\n",getpid());
- 14 sleep(1);
- 15 }
- 16
- 17 return 0;
- 18 }
复制代码 接下来我们来观察一下:
在lesson12路径下也成功创建了新文件log.txt。所以我可以更改进程的工作路径,默认是在可执行程序的路径下。
2 进程状态
2.1 谈谈Linux进程状态
进程状态是task_struct内部的一个属性,int status就是一个代表状态的数字。
看看Linux内核源代码怎么说:
为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在
Linux内核里,进程偶然候也叫做任务)。下面的状态在kernel源代码里界说:
- /*
- * The task state array is a strange "bitmap" of
- * reasons to sleep. Thus "running" is zero, and
- * you can test for combinations of others with
- * simple bit tests.
- */
- static const char * const task_state_array[] = {
- "R (running)", /* 0 */
- "S (sleeping)", /* 1 */
- "D (disk sleep)", /* 2 */
- "T (stopped)", /* 4 */
- "t (tracing stop)", /* 8 */
- "X (dead)", /* 16 */
- "Z (zombie)", /* 32 */
- };
复制代码
- R运行状态(running) : 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
- S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠偶然候也叫做可中断睡眠(interruptible sleep))
- D磁盘休眠状态(Disk sleep)偶然候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
- T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继承运行。
- X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态
接下来我们来验证一下这些状态(D状态无法验证,X状态无法验证)
R 、T、 D状态
写个程序来进行测试:
- 1 #include<stdio.h>
- 2 #include<sys/types.h>
- 3 #include<unistd.h>
- 4
- 5 int main()
- 6 {
- 7 while(1)
- 8 {
- 9 printf("I am a process,pid : %d\n",getpid());//注意这里没有写sleep函数
- 10 }
- 11
- 12 return 0;
- 13 }
复制代码 使用while : ;do ps ajx | head -1&& ps ajx | grep testStatus |grep -v grep ;sleep 1 ;done指令进行实时监控:
可以看到我们右边的可执行程序同等在运行,但是在左边的监控中,却发现是S+状态???这是为什么怎么会是休眠状态(sleep),显着一直在运行啊!?
我们来把printf去掉,再来看看怎么样
- 1 #include<stdio.h>
- 2 #include<sys/types.h>
- 3 #include<unistd.h>
- 4
- 5 int main()
- 6 {
- 7 while(1)
- 8 {
- 9 //printf("I am a process,pid : %d\n",getpid());//注意这里没有写sleep函数
- 10 }
- 11
- 12 return 0;
- 13 }
复制代码 来看运行的效果:
唉?!怎么现在成了R+状态了???怎么现在就是运行状态了???
这个问题到底是怎么一回事儿???
其实这与printf有关,printf的本质是往外设显示器上打印,但是进程是在云服务的cpu上运行的。根据冯诺依曼体系结构,外设的处置惩罚速度要远远小于cpu,所以在显示器的打印过程中,cpu就在等待显示器装备打印停当(也变相证明了cpu运行速度比显示器快的多的多的多!!!)
通过刚刚的证明,说明了:
- S 休眠状态就是CPU在等待“资源”停当。
- 该休眠成为可中断睡眠,随时可以被外界唤醒。
- 代表子啊前台运行,在./ 可执行程序 后加&会在背景运行,就不带加号了。
在来看暂停状态 : T(让进程先暂停,等待被唤醒)
使用 kill 下令可以进程发信号,kill具有以下信号(宏界说信号):
- 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
- 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
- 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
- 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
- 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
- 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
- 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
- 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
- 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
- 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
- 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
- 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
- 63) SIGRTMAX-1 64) SIGRTMAX
复制代码 此中的 -19 可以完成暂停 -18 可以让暂停状态继承运行。
来看演示:
如许直观就可以看到暂停状态了。
这个 t 暂停状态多在gdb调试里常见,我们俗称的断点就是做到使进程暂停的作用。即调试暂停
感兴趣可以自行查看哦。
D 状态
这个状态也叫也叫不可中断睡眠状态,是内存为了掩护数据不得不接纳的删除进程操纵,一般不会遇见。
2.2 僵尸进程和孤儿进程
接下来我们来了解僵尸进程和孤儿进程。
Z(zombie)-僵尸进程
- 僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()体系调用)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
- 僵死进程会以停止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
- 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
这个状态类似有人受害,被抛尸荒原,警察一定会封锁现场,法医进行甄别,最后是家属来准备后事。
所以进程也需要有人来把他收走,准备后事。
我们写一段代码来看看:
- 1 #include<stdio.h>
- 2 #include<sys/types.h>
- 3 #include<unistd.h>
- 4
- 5 int main()
- 6 {
- 7 pid_t id = fork();
- 8 if(id == 0)
- 9 {
- 10 int cnt = 5;
- 11 while(cnt--)
- 12 {
- 13 printf("I am child,cnt: %d ,pid: %d \n",cnt,getpid());
- 14 sleep(1);
- 15 }
- 16 }
- 17 else
- 18 {
- 19 while(1)
- 20 {
- 21 printf("I am parent,running always,pid: %d\n",getpid());
- 22 sleep(1);
- 23 }
- 24 }
- 25 }
复制代码 这个代码子进程运行五次就会停止,让我们看看效果:
当cnt小于0时,就结束了进程,于是子进程就成为了僵尸进程。依然就要PID但是不在进行运行。
此中的<defunct>表示被抛弃的,不运行的。
僵尸进程就是:已经运行完毕,但是需要维持自己的退出信息,在自己的进程task_struct中记录自己的信息,将来让父进程来进行读取。如果没有父进程进行读取,僵尸进程会一直存在(会引起内存泄漏问题)。
僵尸进程危害
- 进程的退出状态必须被维持下去,(因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了)。可父进程如果一直不读取,那子进程就一直处于Z状态,进而引起内存泄漏!
- 维护退出状态本身就是要用数据维护,也属于进程根本信息,所以保存在task_struct(PCB)中,换句话说, Z状态一直不退出, PCB一直都要维护!
- 那一个父进程创建了很多子进程,就是不接纳,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C语言中界说一个结构体变量(对象),是要在内存的某个位置进行开发空间!
孤儿进程
再来看孤儿进程(与僵尸进程相反,孤儿进程是父进程运行完毕了):
- 父进程如果提前退出,那么子进程后退出,进入Z之后,那该怎样处置惩罚呢?
- 父进程先退出,子进程就称之为“孤儿进程”
- 孤儿进程被1号init进程领养,固然要有init进程接纳喽
这个就类似孤儿,我们写代码来测试一下:
- 1 #include<stdio.h>
- 2 #include<sys/types.h>
- 3 #include<unistd.h>
- 4
- 5 int main()
- 6 {
- 7 pid_t id = fork();
- 8 if(id == 0)
- 9 {
- 10
- 11 while(1)
- 12 {
- 13 printf("I am child,running always,pid: %d \n",getpid());
- 14 sleep(1);
- 15 }
- 16 }
- 17 else
- 18 {
- 19 int cnt = 5;
- 20 while(cnt--)
- 21 {
- 22 printf("I am parent,cnt:%d,pid: %d\n",cnt,getpid());
- 23 sleep(1);
- 24 }
- 25 }
- 26 }
复制代码 这个代码父进程运行五次就会停止,让我们看看效果:
如许子进程就变成了孤儿进程STAT。
孤儿进程在运行结束后,会被1号进程(操纵体系本身)进行领养,保证子进程正常被接纳!
2.3 浅谈进程的阻塞、挂起和运行
这个是操纵体系的宏观理论(指导思想),对于任意一门操纵体系都实用!!!
- 而进程会在运行队列中,该进程的状态就是R状态!!!也就是图中的停当状态。
- 在CPU中进程会按时间片轮转调度(比如每2ms更换运算的进程),让多个进程以切换的方式进行调度,在一个时间段中得以推进代码,就叫做并发!!!
- 在任何时候,都同时有多个进程在同时运行,就叫做并行!!!
- 那什么是阻塞态呢???
就是将其列入装备的等待队列中(比如scanf 等待j键盘输入),完成会回返回运行队列,唤醒。这就是等待队列
- 什么是挂起态呢???
挂起态,是一个表示进程被停滞的特殊状态。在此状态下,进程不会在主存中活跃,而是被转移到辅助存储器(如硬盘 的 swap)中。这 意味着进程在此状态下不会获得CPU的执行时间,并从运行队列中移除,也就被挂起到外设当中了!!!这是一种效率换取空间的办法。
送给我们一句话:
如果痛恨所处的黑暗,请你成为你想要的光。 —— 顾城
Thanks♪(・ω・)ノ谢谢阅读!!!
下一篇文章见!!!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |