做网站排名的,合肥建设银行网站,网站上的格式用html怎么做,如何卸载微wordpress25.1 进程的终止#xff1a;_exit()和exit() 440 
1. _exit(int status)#xff0c; status 定义了终止状态#xff0c;父进程可调用 wait 获取。仅低8位可用#xff0c;调用 _exit() 总是成功的。
2.程序一般不会调用 _exit()#xff0c; 而是调用库函数 exit()。exit() …25.1 进程的终止_exit()和exit() 440 
1. _exit(int status) status 定义了终止状态父进程可调用 wait 获取。仅低8位可用调用 _exit() 总是成功的。
2.程序一般不会调用 _exit() 而是调用库函数 exit()。exit() 执行如下动作1.调用退出处理程序(通过 atexit() 和 on_exit() 注册的函数)其执行顺序与注册顺序相反。2.刷新 stdio 流缓冲区3.使用由 status 提供的值执行 _exit() 系统调用。
与专属的Unix的 _exit 不同 exit() 则属于标准C语言函数库。25.2 进程终止的细节 441 
无论进程是否正常终止都会发生如下动作 1.关闭所有打开文件描述符目录流信息目录描述符以及转换描述符 2.作为文件描述符关闭的后果之一将释放该进程所持有的任何文件锁 3.分离任何已经连接的 System V 共享内存段且对应于各段的 shm_nattch 计数器值减一 4.进程为每个 System V 信号量所设置的 semadj 值将会被加到信号量值中。 5.如果该进程是一个管理终端的管理进程那么系统会向该终端前台进程组中的每个进程发送 sighup 信号 接着终端会于会话脱离。 6.将关闭该进程打开的任何 POSIX 有名信号量类似调用 sem_close() 7.将关闭该进程打开的任何 POSIX 消息队列类似于调用 mq_close() 8.作为进程退出的后果之一如果某进程组称为孤儿且该组中存在任何已停止进程则组中所有进程都将收到 sighup 信号随着为 sigcont 信号。 9.移除该进程通过 mlock() 和 mlockall() 锁建立的任何内存锁 10.取消该进程调用 mmap() 所创建的任何内存映射。 
25.3 退出处理程序 442 
退出处理程序是一个由程序设计者提供的函数可于进程生命周期的任意时间点注册并在该进程调用 exit() 正常终止时 自动执行。如果程序直接调用 _exit() 或者因信号而异常终止则不会调用退出处理程序。 当程序收到信号而终止时将不会调用退出处理程序。这一事实一定程序上限制了它们的效用。此时最佳的应对方式莫若为可能发送 给进程的信号建立信号处理程序并于其中设置标志位领主程序据此来调用 exit()。因为 exit() 不属于异步信号安全函数所有通常 不能在信号处理程序中对其发起调用。 注册退出处理程序 atexit(); 1.概念一般内核中每个启动的进程默认都有一个标准的默认终止函数用于在进程终止时执行的函数该函数主要用来释放进程所占用的资源也可以自定义终止函数。按照ISO C规定一个进程可以注册32个终止函数这些函数将由exit函数自动调用。    登记的终止函数以栈的形式运行先注册的后执行。如果自定义注册了进程终止函数那么内核提供的默认的终止函数将会被覆盖。 原文链接https://blog.csdn.net/qq_35733751/article/details/82392918 希望进程在结束时进行一些清理工作比如某些重要的数据保存到文件中。如果不登记终止函数的话实现这个操作是有些困难的因为进程有可能是因为某个函数调用失败且该函数出错时又调用了exit函数导致进程终止更糟糕的是出错的函数是不确定的。这个时候就可以通过登记注册终止函数这样进程在终止时会自动执行注册的终止函数把数据保存到文件中方便了许多。 2. atexit函数语义   atexit函数是用来在内核中注册一个进程终止时执行的函数通过atexit函数所包含的头文件来看atexit函数是一个C库函数。 
函数原型 
#include stdlib.h
int atexit(void(*function)(void));atexit函数的参数是一个函数指针表示注册的终止函数终止函数语法格式为void(*function)(void) 。返回值成功返回0失败返回不一定是-1
#include stdio.h
#include stdlib.h
#include unistd.h
#include fcntl.h
#include string.h//以下func1func2func3都是线程终止函数
void term_func1(void){puts(term func1);
}
void term_func2(void){puts(term func2);
}
void term_func3(void){puts(term func3);
}int main(int argc , char *args[]){if(argc  3){fprintf(stderr,use: %s file[exit | _exit | return]\n ,args[0]);exit(0);}//注册终止函数atexit(term_func1);atexit(term_func2);atexit(term_func3);//打开文件FILE *fp  fopen(args[1] , w);if(NULL  fp){perror(fopen);exit(-1);}//向文件写入数据fprintf(fp , hello linux);if(!strcmp(args[2], exit)){exit(0);        //标准C库函数}else if(!strcmp(args[2], _exit)){_exit(0);       //系统调用}else if(!strcmp(args[2], return)){return 0;       //正常返回}else{fprintf(stderr,use: %s file[exit | _exit | return]\n, args[0]);}exit(0);
}通过atexit函数注册的终止函数并非在所有情况下都会被调用是否调用终止函数这取决于进程的终止方式 
(base) wannian07wannian07-PC:~/Desktop/std/linux prog$ gcc -o atexit_process atexit_process.c -lpthread (base) wannian07wannian07-PC:~/Desktop/std/linux prog$ ./atexit_process test.txt return term func3 term func2 term func1 (base) wannian07wannian07-PC:~/Desktop/std/linux prog$ cat test.txt hello linux 当前进程以return形式退出终止函数是以栈的形式执行的先注册的终止函数后执行。然后通过cat命令查看test.txt文件的内容为hello linux 。 (base) wannian07wannian07-PC:~/Desktop/std/linux prog$ ./atexit_process test.txt exit term func3 term func2 term func1 (base) wannian07wannian07-PC:~/Desktop/std/linux prog$ cat test.txt hello linux exit方式和return方式的结果是一样的也调用了注册的终止函数。 
(base) wannian07wannian07-PC:~/Desktop/std/linux prog$ ./atexit_process test.txt _exit (base) wannian07wannian07-PC:~/Desktop/std/linux prog$ cat test.txt _exit方式和前两种有所不同之前注册的进程终止函数一个都没有执行另外test.txt文件倒是创建了但是使用cat命令查看文件中并没有内容。 总结 
不同的进程终止方式会产生不同的结果如果我们选择return方式和exit方式进程在终止之前会调用注册的进程终止函数但是选择_exit方式就算注册了终止函数进程在终止之前也不会调用。 
另外需要注意的是在程序中写入文件数据用的函数是一个标准C库函数在使用fprintf函数写入数据时实际上数据并不会写入文件而是先写入buff缓冲区中这种方式也叫全缓存只有当缓冲区写满或者调用fclose函数才会把数据写入文件中。 
当程序终止时也会把数据写入文件但是会有一些区别如果使用return方式和exit方式让程序退出会刷新buf中的数据到文件中但是以_exit方式让程序退出是不会刷新数据到文件中。 
_exit是系统调用进程终止前不会调用终止函数也不会刷新数据到文件中而是直接进入内核。而exit和return是标准库函数进程终止前会调用终止函数也会刷新数据到文件中。 
因此我们可以把进程终止方式简单总结为:  
图1-进程终止方式 
进程启动和退出——atexit函数 
下面这种图也证实了exit函数内部调用了_exit函数。 
图2-进程的启动和退出过程  
进程的启动和退出过程大概如图2所示   1进程在运行时首先内核会先启动一个例程这个例程的作用是加载程序运行的参数环境变量在内核注册终止函数等这些工作然后启动例程会调用main函数。 
2main函数调用了exit函数使进程终止退出在进程终止之前如果注册了终止函数那么exit函数会先去依次调用进程终止函数注册了几个就调用几个每调用完一个终止函数并返回调用顺序是以栈的形式来调用然后调用flush刷新IO缓冲区的数据再返回最后调用了系统调用_exit或_Exit然后进程终止退出。 
3值得注意的是main函数也可以通过调用系统调用_exit直接进入内核使进程终止并退出通过调用系统调用的方式使进程终止的话并不会调用注册的进程终止函数。也可以通过main函数调用用户函数然后用户函数调用exit然后依次调用进程终止函数再调用标准I/O函数刷新缓冲区最后调用系统调用_exit使进程终止退出。 
4当然用户函数也是可以直接通过系统调用_exit()进入内核使进程终止退出的。 原文链接https://blog.csdn.net/qq_35733751/article/details/82392918 一个操作系统的实现https://blog.csdn.net/chuanwang66/category_8332297.html on_exit(); 用来注册执行exit()函数前执行的终止处理程序。 函数声明 
#include stdlib.h int on_exit(void (*function)(int  void *) void *arg); 
功能描述   on_exit()用来注册终止处理程序当程序通过调用exit()或从main 中返回时被调用 终止处理程序有两个参数第一个参数是来自最后一个exit()函数调用中的status第二个参数是来自on_exit()函数中的arg   同一个函数若注册多次那它也会被调用多次   当一个子进程是通过调用fork()函数产生时它将继承父进程的所有终止处理程序。在成功调用exec系列函数后所有的终止处理程序都会被删除。 返回值 
成功返回0失败返回非0值。 
#define _BSD_SOURCE     /* Get on_exit() declaration from stdlib.h */
#include stdlib.h
#include tlpi_hdr.h#ifdef __linux__        /* Few UNIX implementations have on_exit() */
#define HAVE_ON_EXIT
#endifstatic void
atexitFunc1(void)
{printf(atexit function 1 called\n);
}static void
atexitFunc2(void)
{printf(atexit function 2 called\n);
}#ifdef HAVE_ON_EXIT
static void
onexitFunc(int exitStatus, void *arg)
{printf(on_exit function called: status%d, arg%ld\n,exitStatus, (long) arg);
}
#endifint
main(int argc, char *argv[])
{
#ifdef HAVE_ON_EXITif (on_exit(onexitFunc, (void *) 10) ! 0)fatal(on_exit 1);
#endifif (atexit(atexitFunc1) ! 0)fatal(atexit 1);if (atexit(atexitFunc2) ! 0)fatal(atexit 2);
#ifdef HAVE_ON_EXITif (on_exit(onexitFunc, (void *) 20) ! 0)fatal(on_exit 2);
#endifexit(2);
}(base) wannian07wannian07-PC:~/Desktop/std/linux prog$ gcc exit_handlers.c -o exit_handlers error_functions.c curr_time.c get_num.c (base) wannian07wannian07-PC:~/Desktop/std/linux prog$ ./exit_handlers on_exit function called: status2, arg20 atexit function 2 called atexit function 1 called on_exit function called: status2, arg10 
25.4 fork()、stdio缓冲区以及_exit()之间的交互 445 
#include tlpi_hdr.hint
main(int argc, char *argv[])
{printf(Hello world\n);write(STDOUT_FILENO, Ciao\n, 5);if (fork()  -1)errExit(fork);/* Both child and parent continue execution here */exit(EXIT_SUCCESS);
} (base) wannian07wannian07-PC:~/Desktop/std/tlpi-dist/procexec$ make fork_stdio_buf cc -stdc99 -D_XOPEN_SOURCE600 -D_DEFAULT_SOURCE -g -I…/lib -pedantic -Wall -W -Wmissing-prototypes -Wno-sign-compare -Wno-unused-parameter fork_stdio_buf.c …/libtlpi.a …/libtlpi.a -lm -o fork_stdio_buf (base) wannian07wannian07-PC:~/Desktop/std/tlpi-dist/procexec$ ./fork_stdio_buf Hello world Ciao (base) wannian07wannian07-PC:~/Desktop/std/tlpi-dist/procexec$ ./fork_stdio_buf  a (base) wannian07wannian07-PC:~/Desktop/std/tlpi-dist/procexec$ cat a Ciao Hello world Hello world 
printf() 信息输出了2次是在进程的用户空间内存维护 stiod 缓冲区的。因此通过 fork 创建的子进程会复制这些缓冲区。父子进程调用 exit() 时会各自刷新 stdio 缓冲区从而导致重复输出。 
可以采用以下2种方法避免 1.可以在调用 fork 之前使用 fflush() 来刷新 stdio 缓冲区作为另外一种选择使用 setvbuf() 和 setbuf() 来关闭 stdio 流缓冲。 2.子进程可以调用 _exit() 而非 exit()以便不刷新 stdio 缓冲区。 这一技术例证了更为通用的原则在创建子进程的应用中典型情况下仅一个进程(一般为父进程)应通过调用 exit() 终止而其他进程应调用 _exit()终止 从而确保一个进程调用退出处理程序刷新 stdio 缓冲区。 
write 并未出现2次是因为 write 会将数据直接传递给内核缓冲区fork 不会复制这一缓冲区。 文章转载自: http://www.morning.mslhq.cn.gov.cn.mslhq.cn http://www.morning.jngdh.cn.gov.cn.jngdh.cn http://www.morning.nrydm.cn.gov.cn.nrydm.cn http://www.morning.zphlb.cn.gov.cn.zphlb.cn http://www.morning.xrwtk.cn.gov.cn.xrwtk.cn http://www.morning.lsjtq.cn.gov.cn.lsjtq.cn http://www.morning.lqlhw.cn.gov.cn.lqlhw.cn http://www.morning.tkyry.cn.gov.cn.tkyry.cn http://www.morning.bwnd.cn.gov.cn.bwnd.cn http://www.morning.gcftl.cn.gov.cn.gcftl.cn http://www.morning.jwncx.cn.gov.cn.jwncx.cn http://www.morning.nrrzw.cn.gov.cn.nrrzw.cn http://www.morning.jhwwr.cn.gov.cn.jhwwr.cn http://www.morning.frsxt.cn.gov.cn.frsxt.cn http://www.morning.srky.cn.gov.cn.srky.cn http://www.morning.zcqtr.cn.gov.cn.zcqtr.cn http://www.morning.pjwfs.cn.gov.cn.pjwfs.cn http://www.morning.pftjj.cn.gov.cn.pftjj.cn http://www.morning.pccqr.cn.gov.cn.pccqr.cn http://www.morning.yjfzk.cn.gov.cn.yjfzk.cn http://www.morning.kysport1102.cn.gov.cn.kysport1102.cn http://www.morning.ccphj.cn.gov.cn.ccphj.cn http://www.morning.mngyb.cn.gov.cn.mngyb.cn http://www.morning.ktblf.cn.gov.cn.ktblf.cn http://www.morning.kqgsn.cn.gov.cn.kqgsn.cn http://www.morning.wbfg.cn.gov.cn.wbfg.cn http://www.morning.mhcys.cn.gov.cn.mhcys.cn http://www.morning.xqqcq.cn.gov.cn.xqqcq.cn http://www.morning.prqdr.cn.gov.cn.prqdr.cn http://www.morning.ghrhb.cn.gov.cn.ghrhb.cn http://www.morning.ndcf.cn.gov.cn.ndcf.cn http://www.morning.drnfc.cn.gov.cn.drnfc.cn http://www.morning.ydwnc.cn.gov.cn.ydwnc.cn http://www.morning.sthgm.cn.gov.cn.sthgm.cn http://www.morning.mkxxk.cn.gov.cn.mkxxk.cn http://www.morning.gjqgz.cn.gov.cn.gjqgz.cn http://www.morning.xqcbz.cn.gov.cn.xqcbz.cn http://www.morning.jpkhn.cn.gov.cn.jpkhn.cn http://www.morning.rnmyw.cn.gov.cn.rnmyw.cn http://www.morning.qjxkx.cn.gov.cn.qjxkx.cn http://www.morning.rhchr.cn.gov.cn.rhchr.cn http://www.morning.glbnc.cn.gov.cn.glbnc.cn http://www.morning.rblqk.cn.gov.cn.rblqk.cn http://www.morning.bxczt.cn.gov.cn.bxczt.cn http://www.morning.cczzyy.com.gov.cn.cczzyy.com http://www.morning.znkls.cn.gov.cn.znkls.cn http://www.morning.tlfzp.cn.gov.cn.tlfzp.cn http://www.morning.yhglt.cn.gov.cn.yhglt.cn http://www.morning.fksrg.cn.gov.cn.fksrg.cn http://www.morning.tpssx.cn.gov.cn.tpssx.cn http://www.morning.mxnhq.cn.gov.cn.mxnhq.cn http://www.morning.dglszn.com.gov.cn.dglszn.com http://www.morning.qqhfc.cn.gov.cn.qqhfc.cn http://www.morning.jbxmb.cn.gov.cn.jbxmb.cn http://www.morning.ktblf.cn.gov.cn.ktblf.cn http://www.morning.dmlsk.cn.gov.cn.dmlsk.cn http://www.morning.wdpbq.cn.gov.cn.wdpbq.cn http://www.morning.pbksb.cn.gov.cn.pbksb.cn http://www.morning.xhftj.cn.gov.cn.xhftj.cn http://www.morning.djlxz.cn.gov.cn.djlxz.cn http://www.morning.zbjfq.cn.gov.cn.zbjfq.cn http://www.morning.benqc.com.gov.cn.benqc.com http://www.morning.ftlgy.cn.gov.cn.ftlgy.cn http://www.morning.gyqnp.cn.gov.cn.gyqnp.cn http://www.morning.xqndf.cn.gov.cn.xqndf.cn http://www.morning.nkjpl.cn.gov.cn.nkjpl.cn http://www.morning.jgcxh.cn.gov.cn.jgcxh.cn http://www.morning.kgmkl.cn.gov.cn.kgmkl.cn http://www.morning.wnxqf.cn.gov.cn.wnxqf.cn http://www.morning.ppwdh.cn.gov.cn.ppwdh.cn http://www.morning.hdnd.cn.gov.cn.hdnd.cn http://www.morning.cjmmt.cn.gov.cn.cjmmt.cn http://www.morning.pwbps.cn.gov.cn.pwbps.cn http://www.morning.jxlnr.cn.gov.cn.jxlnr.cn http://www.morning.nqpy.cn.gov.cn.nqpy.cn http://www.morning.dgng.cn.gov.cn.dgng.cn http://www.morning.ntqqm.cn.gov.cn.ntqqm.cn http://www.morning.ghxzd.cn.gov.cn.ghxzd.cn http://www.morning.bpmdn.cn.gov.cn.bpmdn.cn http://www.morning.jltmb.cn.gov.cn.jltmb.cn