exit()与析构函数
exit()和析构函数的关系_exit会调用析构函数吗_ZM_iTUDOU的博客-CSDN博客
exit() 函数是用来终止程序的执行,并将控制权返回到操作系统。
1、不会调用局部对象的析构函数。
2、会调用全局对象的析构函数
return 会调用局部和全局对象的局部析构函数
exit()和return区别
return是语言级别的,它表示了调用堆栈的返回;return( )是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一层调用。在多个进程时。如果有时要检测上个进程是否正常退出。就要用到上个进程的返回值,依次类推。而exit是系统调用级别的,它表示了一个进程的结束。
析构函数是在对象被销毁之前自动调用的函数。它用于清理对象在创建时所分配的内存,释放资源以及做一些额外的清理工作。如果在程序结束时不调用析构函数,这些资源可能会被遗漏或泄漏。
因此,exit()函数和析构函数都是用于程序的清理工作,但目的不同。exit()函数用于程序终止,而析构函数用于对象销毁前的清理工作。在正常情况下,应该让程序自然结束,调用析构函数释放资源。只有在特殊情况下,如程序出现无法处理的错误时,才需要使用 exit() 函数强制结束程序执行。
linux系统编程之进程(八):守护进程详解及创建,daemon()使用 - mickole - 博客园 (cnblogs.com)
// 程序运行的日志。
CLogFile logfile;
int main(int argc,char *argv[])
{
// 程序的帮助。
if (argc != 2)
{
printf("\n");
printf("Using:./checkproc logfilename\n");
printf("Example:/project/tools1/bin/procctl 10 /project/tools1/bin/checkproc /tmp/log/checkproc.log\n\n");
printf("本程序用于检查后台服务程序是否超时,如果已超时,就终止它。\n");
printf("注意:\n");
printf(" 1)本程序由procctl启动,运行周期建议为10秒。\n");
printf(" 2)为了避免被普通用户误杀,本程序应该用root用户启动。\n");
printf(" 3)如果要停止本程序,只能用killall -9 终止。\n\n\n");
return 0;
}
// 忽略全部的信号和IO,不希望程序被干扰。
CloseIOAndSignal(true);
}
// 忽略全部的信号和IO,不希望程序被干扰。
CloseIOAndSignal(true);
// 打开日志文件。
if (logfile.Open(argv[1],"a+")==false)
{ printf("logfile.Open(%s) failed.\n",argv[1]); return -1; }
int shmid=0;
// 创建/获取共享内存,键值为SHMKEYP,大小为MAXNUMP个st_procinfo结构体的大小。
if ( (shmid = shmget((key_t)SHMKEYP, MAXNUMP*sizeof(struct st_procinfo), 0666|IPC_CREAT)) == -1)
{
logfile.Write("创建/获取共享内存(%x)失败。\n",SHMKEYP); return false;
}
// 将共享内存连接到当前进程的地址空间。
struct st_procinfo *shm=(struct st_procinfo *)shmat(shmid, 0, 0);
// 遍历共享内存中全部的记录。
for (int ii=0;ii<MAXNUMP;ii++)
{
// 如果记录的pid==0,表示空记录,continue;
if (shm[ii].pid==0) continue;
// 如果记录的pid!=0,表示是服务程序的心跳记录。
// 程序稳定运行后,以下两行代码可以注释掉。
//logfile.Write("ii=%d,pid=%d,pname=%s,timeout=%d,atime=%d\n",\
// ii,shm[ii].pid,shm[ii].pname,shm[ii].timeout,shm[ii].atime);
// 向进程发送信号0,判断它是否还存在,如果不存在,从共享内存中删除该记录,continue;
int iret=kill(shm[ii].pid,0);
if (iret==-1)
{
logfile.Write("进程pid=%d(%s)已经不存在。\n",(shm+ii)->pid,(shm+ii)->pname);
memset(shm+ii,0,sizeof(struct st_procinfo)); // 从共享内存中删除该记录。
continue;
}
time_t now=time(0); // 取当前时间。
// 如果进程未超时,continue;
if (now-shm[ii].atime<shm[ii].timeout) continue;
// 如果已超时。
logfile.Write("进程pid=%d(%s)已经超时。\n",(shm+ii)->pid,(shm+ii)->pname);
// 发送信号15,尝试正常终止进程。
kill(shm[ii].pid,15);
// 每隔1秒判断一次进程是否存在,累计5秒,一般来说,5秒的时间足够让进程退出。
for (int jj=0;jj<5;jj++)
{
sleep(1);
iret=kill(shm[ii].pid,0); // 向进程发送信号0,判断它是否还存在。
if (iret==-1) break; // 进程已退出。
}
// 如果进程仍存在,就发送信号9,强制终止它。
if (iret==-1)
logfile.Write("进程pid=%d(%s)已经正常终止。\n",(shm+ii)->pid,(shm+ii)->pname);
else
{
kill(shm[ii].pid,9); // 如果进程仍存在,就发送信号9,强制终止它。
logfile.Write("进程pid=%d(%s)已经强制终止。\n",(shm+ii)->pid,(shm+ii)->pname);
}
// 从共享内存中删除已超时进程的心跳记录。
memset(shm+ii,0,sizeof(struct st_procinfo)); // 从共享内存中删除该记录。
}
// 把共享内存从当前进程中分离。
shmdt(shm);
return 0;
}