exit函数使用很简单,效果就是退出一个进程(我觉得应该叫销毁一个进程,执行后这个进程就会被销毁).
exit的作用是终止一个进程,并释放其资源。注:exit不会使一个进程灰飞烟灭,前面我们在fork一个进程时候,谈到了进程资源,包括用户空间,进程信号表,文件和系统堆栈空间,执行exit以后进程进入一种僵死状态,不再会被系统调度,释放了除系统堆栈以外所有的资源。(就是保持了一个最小资源,用于父进程的检查)可能有人不太理解为什么不回收系统堆栈空间,下面是个人理解:第一:实现起来有难度,在CPU上运行的是进程不是代码,是进程自然需要一个task_struct来支持它的运行。exit也不例外,在运行exit的代码时候,它所属的进程的task_struct仍然是它需要毁灭的进程的PCB,如果它销毁task_struct,它将会如何执行呢,我想大概会报出段错误,从而导致系统的崩溃,而task_struct位置正是系统堆栈空间的低地址。第二,task_struct保存了信息可以留给父进程使用。不释放这部分空间未必是坏事。(玩笑,死人是没法处理自己的尸体的,都是被他人处理或者自然腐烂,有意义的就是有个坟墓或者传记给活人瞻仰,崇拜和精神寄托,所以坟墓是给活人用的).毕竟计算机资源有限,资源不释放最终会导致资源耗尽,关于僵死下的系统堆栈空间的释放是由父进程调用wait4来完成的。
下面就是exit的实现,我们将会依次看到进程在死亡前夕陆续释放自己的用户空间,进程信号表,文件资源,然后就是死亡前夕的检测工作,包括托孤(将自己所属的子进程托管给其他进程照料,主要是托管给系统初始化进程init)和从进程的关系网中撤离.sys_exit是exit的实现:
482 asmlinkage long sys_exit(int error_code)
483 {
484 do_exit((error_code&0xff)<<8);
485 }
下面就是do_exit的代码:首先看到的是返回是void至于NORET_TYPE就更不用管了,他被定义成了/**/,void就是不会返回了,exit自然不会返回,进程都被消亡了,他能返回到哪儿呢?
421 NORET_TYPE void do_exit(long code)
422 {
423 struct task_struct *tsk = current;
424
425 if (in_interrupt()) //中断进程不允许退出,否则麻烦大了,可以想象你调用了一个键盘驱动导致你的程序退出,你会怎么想?
426 panic("Aiee, killing interrupt handler!");
427 if (!tsk->pid) //0号进程是系统空转进程不允许退出
428 panic("Attempted to kill the idle task!");
429 if (tsk->pid == 1) //1号系统初始化进程不允许退出
430 panic("Attempted to kill init!");
431 tsk->flags |= PF_EXITING;
432 del_timer_sync(&tsk->real_timer); //进程退出之前可能设置了计时器,即将撤销时自然要撤销计时器,关于计时器作用,这里就不说明了
433
434 fake_volatile:
435 #ifdef CONFIG_BSD_PROCESS_ACCT
436 acct_process(code);
437 #endif
438 __exit_mm(tsk); //撤销存储空间
439
440 lock_kernel();
441 sem_exit(); //撤销信号量,信号量是用于进程通信的资源
442 __exit_files(tsk); //撤销打开文件
443 __exit_fs(tsk); //撤销工作目录
444 exit_sighand(tsk); //撤销信号处理表,这些资源撤销,可以看一下exit资源撤销
445 exit_thread(); //对于i386处理器,这是个一空的语句
446
447 if (current->leader)
448 disassociate_ctty(1);//如果一个进程是一个session的主进程,那么整个session与其主控制端要脱离
449
450 put_exec_domain(tsk->exec_domain);
451 if (tsk->binfmt && tsk->binfmt->module)
452 __MOD_DEC_USE_COUNT(tsk->binfmt->module);
453
454 tsk->exit_code = code;
455 exit_notify(); //通知父进程料理自己的后事,个人觉得像是自己在立遗嘱
456 schedule(); //从exit_notify中退出后,我们就处理掉了即将死亡进程和其它进程直接的关系,也通知了父进程回收工作,前面说过do_exit不返回就是由于schedule不会返回,正常情况下schedule是会返回的,它的作用是按照调度选择合适的进程来运行,而这里该进程已经僵死,不会再被运行,所以这里的schedule不会再返回
457 BUG();
458 /*
459 * In order to get rid of the "volatile function does return" message
460 * I did this little loop that confuses gcc to think do_exit really
461 * is volatile. In fact it's schedule() that is volatile in some
462 * circumstances: when current->state = ZOMBIE, schedule() never
463 * returns.
464 *
465 * In fact the natural way to do all this is to have the label and the
466 * goto right after each other, but I put the fake_volatile label at
467 * the start of the function just in case something /really/ bad
468 * happens, and the schedule returns. This way we can try again. I'm
469 * not paranoid: it's just that everybody is out to get me.
470 */
471 goto fake_volatile;
472 }
分享到:
相关推荐
在使用 fork 函数时,为什么在子进程分支中使用 _exit 函数而不使用 exit 函数?这是因为 exit 函数会执行一些退出处理,例如关闭打开的文件、释放资源等,而 _exit 函数不会执行这些退出处理,这样可以避免子进程在...
分析了该编码系统的EXIT函数,以EXIT误差函数为代价函数,提出了自适应OFDMLDPC编码方案。该方案与传统自适应方案相比,不需要确定切换门限,数值计算简单,而且避免了计算子信道信噪比带来的误差,适用于高速通信...
Exit函数是一种终止当前进程的方式,exit函数的原型为`void exit(int status);`,其中status是进程的退出状态,通常情况下,exit(0)表示进程正常退出,而exit(1)或exit(-1)表示进程异常退出。exit函数会结束当前...
调用C标准库的exit函数详解 在C语言中,exit函数是一种标准库函数,用于终止程序的执行並返回状态码给操作系统。下面将详细介绍如何调用C标准库的exit函数。 1. exit函数的定义 exit函数的定义在stdlib.h头文件中...
在C语言中,`atexit`和`exit`函数是两个关键的进程控制函数,它们在程序生命周期的不同阶段发挥重要作用。 `atexit`函数用于注册一个在程序正常退出时需要执行的函数。按照ISO C标准,一个进程最多可以注册32个这样...
C++常用系统函数 C++语言在编程时,许多基本和重要的功能都由系统的库函数和类库来实现。这些库函数和类库提供了丰富的功能,涵盖缓冲区操作、字符分类、数据转换、目录控件...* _cexit函数:终止当前进程,释放资源。
5. **`exit.c`和`exit.h`文件**:在项目中,`exit.c`通常是实现外部中断服务函数和相关功能的源代码文件,而`exit.h`则包含了相关的函数声明和可能的全局变量定义,供其他模块调用。 6. **`exit.zip`文件**:这是一...
这时”exit”过早的结束了这个函数。可是当你没有保存当前脚本或当你调用的是一个交互函数,你整个Powershell宿主将关闭。 “Exit”结束当前调用的脚本,不仅仅是函数。倘若你把它像下面那样保存到脚本,你也许会有...
在main函数返回之前,或调用exit函数时,程序会结束运行。exit函数原型为:void exit(int status); 其中status参数用来表示程序的退出状态,通常非零值表示异常终止,零值表示正常终止。 6. free函数:用于释放之前...
imx6ull_exit_int
exit 函数可以终止程序并指定返回值。 4. kill 函数 kill 函数可以发送信号来终止进程。 二、数学函数 数学函数提供了多种数学运算,例如 sin、cos、tan、sqrt 等。 三、字符串处理函数 字符串处理函数提供了...
pthread_exit 函数用于终止当前线程。 例如: ```c void *retval = NULL; pthread_exit(retval); ``` 17. 退出线程 pthread_cancel pthread_cancel 函数用于请求终止一个线程。该函数需要一个参数:要终止的线程的...
此外,还有exit函数用于程序退出,rand和srand用于生成随机数等。 5. **错误处理库**():定义了错误代码,当函数执行失败时,会设置errno变量,提供错误信息。 6. **类型定义库**():包含了一些与平台无关的...
例如,使用#include 来引入C库的头文件,并通过std::exit来替代C语言的exit函数。 在实际编程中,理解并熟练运用这些函数库对于提高开发效率至关重要。例如,对于大规模数据处理,可以利用STL的容器和算法实现高效...
* _c_exit 函数:不终止程序执行,如同_exit 的清除,包含在 process.h 头文件中。 * _cexit 函数:不终止程序执行,如同_exit 的清除,包含在 process.h 头文件中。 三、接口子程序 * _bios_disk 函数:输出 BIOS...
exit函数与_exit函数的最大区别在于exit函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,即所谓的"清理I/O缓冲"。 6. setjmp和longjmp函数 setjmp函数用于设置跳转上下文参数,...
常用的函数有 malloc()、calloc()、realloc()、free()、system()、atoi()、atol()、rand()、srand() 和 exit() 等。 1. calloc 函数: void *calloc(unsigned n, unsigned size),用于分配 n 个数据项的内存连续...
pthread_exit 函数用于结束线程,pthread_join 函数用于等待线程结束。pthread_join 函数的参数包括线程标识符和线程状态指针。 四、线程等待 线程等待是指一个线程等待另一个线程的结束。pthread_join 函数用于...