1 进程终止
共有8种方式 其中5种是正常终止
代码语言:javascript复制1:从 main 返回
2:调用 exit
3:调用 _exit 或 _Exit
4:最后一个线程从其启动例程返回
5:最后一个线程调用 pthread_exit
3种是异常终止
代码语言:javascript复制6:调用 abort
7:接到一个信号并终止
8:最后一个线程对取消请求做出响应
2 exit函数
有三个函数用于正常终止一个程序:_exit和_Exit立即进入内核,exit则先执行一些清理程序(关闭io等),然后进入内核。
代码语言:javascript复制#include <stdlib.h>
void exit(int status);
void _Exit(int status);
#include <unistd.h>
void _exit(int status);
3 atexit函数
按照ISO C的规定,一个进程可以登记多达32个函数,这些函数将由exit自动调用。atexit()注册的函数类型应为不接受任何参数的void函数。 exit调用这些注册函数的顺序与它们 登记时候的顺序相反。同一个函数如若登记多次,则也会被调用多次。 示例:
代码语言:javascript复制#include "apue.h"
static void my_exit1(void);
static void my_exit2(void);
int main(void)
{
if (atexit(my_exit2) != 0)
err_sys("can't register my_exit2");
if (atexit(my_exit1) != 0)
err_sys("can't register my_exit1");
if (atexit(my_exit1) != 0)
err_sys("can't register my_exit1");
printf("main is donen");
return(0);
}
static void my_exit1(void)
{
printf("first exit handlern");
}
static void my_exit2(void)
{
printf("second exit handlern");
}
运行结果:
代码语言:javascript复制$ ./a.out
main is done
first exit handler
first exit handler
second exit handler
3 环境变量
获取环境变量值
代码语言:javascript复制#include <stdlib.h>
char *getenv(const char *name);
Returns: pointer to value associated with name, NULL if not found
4 setjmp和longjmp函数
C语言种,goto是不能跨越函数的,而执行这类跳转功能的函数是setjmp和longjmp。这两个函数对于处理发生在深层嵌套函数调用的出错情况时非常有用的。
代码语言:javascript复制#include <setjmp.h>
int setjmp(jmp_buf env);
Returns: 0 if called directly, nonzero if returning from a call to longjmp
void longjmp(jmp_buf env, int val);
在要返回的地方调用setjmp。参数env是一个特殊的类型jmp_buf ,它存储了调用longjmp所需要的用来恢复栈状态的所有信息。
代码语言:javascript复制#include "apue.h"
#include <setjmp.h>
#define TOK_ADD 5
jmp_buf jmpbuffer;
int main(void)
{
char line[MAXLINE];
if (setjmp(jmpbuffer) != 0)
printf("error");
while (fgets(line, MAXLINE, stdin) != NULL)
do_line(line);
exit(0);
}
Void do_line(char *ptr) /* process one line of input */
{
int cmd;
tok_ptr = ptr;
while ((cmd = get_token()) > 0) {
switch (cmd) { /* one case for each command */
case TOK_ADD:
cmd_add();
break;
}
}
}
Int get_token(void)
{
/* fetch next token from line pointed to by tok_ptr */
}
Void cmd_add(void)
{
int token;
token = get_token();
if (token < 0) /* an error has occurred */
longjmp(jmpbuffer, 1);
/* rest of processing for this command */
}