linux上进程的一些问题

寵の児 提交于 2019-12-05 17:50:06

main进程终止:

                图片来自linux环境高级编程150页

 1 #include<cstdlib>                                                                    
 2 #include<cstdio>                                                                     
 3                                                                                      
 4 static void my_exit1(void)                                                           
 5 {                                                                                    
 6   printf("first exit handler\n");                                                    
 7 }                                                                                    
 8 static void my_exit2(void)                                                           
 9 {                                                                                    
10   printf("second exit handler\n");                                                   
11 }                                                                                    
12                                                                                      
13 int main()                                                                           
14 {                                                                                    
15   if(atexit(my_exit1) != 0)   //#include<cstdlib>先注册的终止处理程序后被调用,FILO                                               
16     printf("error_exit1\n");                                                         
17   if(atexit(my_exit2) != 0)                                                          
18     printf("error_exit2\n");                                                         
19   printf("main is done\n");                                                          
20   exit(0); // == return 0; 0表示终止状态码,正常终止 #include<cstdlib>                                         
21 }

  

 上面代码片段使用不同的链接方式:

  

 获取环境变量(以前的main含有第三个参数:环境变量。最后虽然取消了第三个参数,但是环境变量还是会在程序执行之前传入)

1   const char* env ;                                                                  
2   env = getenv("PATH");  //#include<cstdlib>                                                    
3   printf("PATH = %s",env);  

 fork()系统调用:

  先来张图片:这不就是shell的核心程序吗!在操作系统完成启动后(中间过程登录等略去)会弹出一个shell,shell的主体结构如下,从命令行获取cmd,然后fork()一个进程就行执行,原本的shell程序执行体阻塞

    

 

   这里面有三个问题,①为什么是!fork()?②为什么使用exec()或者说exec()干嘛了?③wait()做什么事情。

  ①fork()是一个系统调用,那么必然触发int0x80中断进入内核态,进入内核态后,fork创建一个子进程(创建进程无非就是分配资源),fork主要创建子进程的pcb以及栈,因为fork创建的子进程和父进程共享代码段,数据段等等,只有子进程进行写入时才会触发写时拷贝机制进行内存的重新分配,写入为子进程分配的内存空间中。有意思的地方到了,fork()完成子进程的创建后,现在已经不仅仅只有父进程一个执行序列了,而是两个执行序列,还有一个是子进程的执行序列,上图if()语句被两个执行序列都执行了(因为子进程共享父进程的代码段),但是区别来了,父进程调用fork返回后的返回值是不等于0的,因此,if条件不会满足,就会跳过if后面的语句去执行wait(),而新创建的子进程执行序列,执行到if语句时,if条件成立,因此会执行exec系统调用。

  ②exec()是个系统调用,因此也要通过int0x80中断进入内核态,调用sys_exec,它的主要作用就是,将cmd程序的入口代码的cs,ip放到内核栈中,当从内核返回时,会进行内核栈的弹栈,就返回到了cmd程序的执行入口。因此exec系统调用成功使fork()出来的子进程去执行一个可执行程序(这不就是shell中输入的那么指令么,例如ls,exec将ls的执行代码的入口地址写入了子进程对应的内核栈中,弹栈时会到ls入口处执行)。

  ③wait():父进程调用wait()后处于一个阻塞状态,父进程开始阻塞,cpu便执行进程调度,子进程成功的被调度后执行。这样就很完美。当然wait还有另个一个作用,不仅仅是阻塞,它阻塞到这里会等待子进程结束,子进程结束后,父进程通过wait()会获得子进程的状态,释放子进程剩余的资源。如果不使用wait,也就是说子进程结束后,父进程不去获取子进程的结束状态,那么该子进程就会成为了僵尸进程。

  ④上诉三个过程加上最上面的main程序启动终止图就更容易理解了。这里的重点便是fork()后实际产生了两个指令序列,以及exec将子进程重父进程共享过来的指令序列进行修改成exec的过程,wait做后续子进程的处理。

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!