进程终止
参考博客
exit()与_exit()的区别
exit() 和 _exit() 的区别
进程正常终止
进程正常终止的方法有3种:
- 执行
exit()
函数 - 执行
_exit()
函数 - 在主函数中执行
return
exit()与_exit()函数
exit()和_exit()的效果都是让程序退出执行,而_exit()用来“尽快”退出
/* Call all functions registered with `atexit' and `on_exit',in the reverse of the order in which they were registered,perform stdio cleanup, and terminate program execution with STATUS. */
extern void exit (int __status) __THROW __attribute__ ((__noreturn__));/* Terminate program execution with the low-order 8 bits of STATUS. */
extern void _exit (int __status) __attribute__ ((__noreturn__));
区别:
- _exit直接进入内核,exit则先执行一些清除处理(在进程退出之前要检查文件状态,将文件缓冲区中的内容写回文件)再进入内核
- 调用_exit函数时,其会关闭进程所有的文件描述符,清理内存以及其他一些内核清理函数,但不会刷新流(stdin,stdout,stderr…),exit函数是在_exit函数之上的一个封装,其会调用_exit,并在调用之前会刷新流
- exit()函数在退出前要检查文件的打开情况,把文件缓冲区的内容写回文件,_exit()函数直接将进程关闭,缓冲区的数据将会丢失
Linux标准函数中,
“缓冲I/O”
的操作,其特征即对应每一个打开的文件,在内存中都有一片缓冲区。每次读文件时,会连续读出若干条记录,在下次读文件时就可以直接从内存的缓冲区读取;同样每次写文件的时候也仅仅是写入内存的缓冲区,等满足了一定的条件(如达到了一定数量或遇到特定字符等),再将缓冲区中的内容一次性写入文件。这种技术大大增加了文件读写的速度
exit()与return
通常在main()之后就没什么待办的事情了,也不会关心exit()和return的差别,但对于C++程序而言,main()中对象的析构函数是在return之后执行的,如果中途调了exit()就不会执行到析构函数
一般情况下,析构函数就是释放对象的资源,而进程退出后,进程所有资源就都被释放了,所以实际上调用exit()退出程序也并不会出现资源泄漏。只是说如果析构函数涉及到与其他进程通信或IO操作等影响到系统其他资源的情况下就要注意了
示例:
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;void exit_func(void)
{cout << "oh yeah!" << endl;
}class Date
{
public:Date(int year1 = 1970, int month1 = 12, int day1 = 31){cout << "Date constructor" << endl;this->year = year1;this->month = month1;this->day = day1;}void printDate(){cout << year << ":" << month << ":" << day << endl;}int isLeapYear() { return 1; }void setDate(int year, int month, int day) {}~Date() { cout << "Date destructor!" << endl; }private:int year;int month;int day;
};class A
{
private:int dataA;public:A() { cout << "A's constructor" << endl; }~A() { cout << "A's destructor!" << endl; }
};class B
{
private:int dataB;A dataClassA;public:B() { cout << "B's constructor" << endl; }~B() { cout << "B's destructor!" << endl; }
};static Date d199;int main(int argc, char *argv[])
{cout << "main start" << endl;Date d1(2022, 6, 14);d1.printDate();static Date d2;A a1;B b1;atexit(exit_func);cout << "main done" << endl;return 0;
}
运行输出:
prejudice@prejudice-VirtualBox:~/Cplus_learning/bin$ ./wait_return
Date constructor
main start
Date constructor
2022:6:14
Date constructor
A's constructor
A's constructor
B's constructor
main done
B's destructor!
A's destructor!
A's destructor!
Date destructor!
oh yeah!
Date destructor!
Date destructor!
将main()中return 0
改为exit(0)
,运行输出:
prejudice@prejudice-VirtualBox:~/Cplus_learning/bin$ ./wait_return
Date constructor
main start
Date constructor
2022:6:14
Date constructor
A's constructor
A's constructor
B's constructor
main done
oh yeah!
Date destructor!
Date destructor!
看到main()中定义的对象的析构没有被调用
进程异常终止
进程异常终止主要有两种方式:
- 进程
接受到特定的信号
。这个信号可以是进程自己产生的,也可以是来自其他进程或内核。例如,进程企图访问越界的内存地址或者是除数为0时,内核都会产生信号中断进程 调用abort
。这其实是第1种情形的特例,因为它产生一个SIGABRT信号
#include <stdlib>/* Abort execution and generate a core-dump. */
extern void abort (void) __THROW __attribute__ ((__noreturn__));
abort()
函数与exit()
、_exit()
函数区别:
- abort()函数异常终止进程,进程的文件描述符未关闭,占用资源未释放
- exit()、_exit()正常终止进程,关闭进程的文件描述符并释放资源
示例:
// C++ code to demonstrate the example of
// abort() function#include <iostream>
#include <stdlib.h>
using namespace std;int main()
{float x, y;while (1){cout << "Input the value of x: ";cin >> x;cout << "Input the value of y: ";cin >> y;if (y == 0){cout << "Value of Y cannot be 0" << endl;abort();}cout << x << "/" << y << ": " << x / y << endl;}return 0;
}
运行输出:
prejudice@prejudice-VirtualBox:~/Cplus_learning/bin$ ./abort
Input the value of x: 2
Input the value of y: 3
2/3: 0.666667
Input the value of x: 4
Input the value of y: 0
Value of Y cannot be 0
已放弃 (核心已转储)