出错处理2——包裹函数
包裹函数(wrapper function)用来执行实际的函数调用,测试其返回值,并在碰到错误时终止进程。书写包裹函数的约定规则是将函数的第一个字母大写。例如
Sem_post(ptr)
在Linux/Unix编程中当遇到一个以大写字母开头的函数名时,它就是我们说的包裹函数。它调用一个名字相同但是相应首字母小写的实际函数,当碰到错误时,包裹函数总是输出一个出错消息后终止。
为什么要用包裹函数呢?我们不已经有了标准的errno变量来返回错误类型了么?因为我们发现线程函数出错时并不设置errno变量;相反,本该设置errno值改由线程函数作为其返回值返回调用者。这意味着我们每次调用任意一个线程函数时,都得分配一个变量来保存函数返回值,然后再调用我们的err_sys函数前,把errno设置成保存的值。
看例程
#include<stdio.h>/*my_err.h*/
#include<stdlib.h>
void err_sys(const char *str)
{
fprintf(stdout, "%s\n", str);
exit(1);
}
/*wrapper.c*/
#include<unistd.h>
#include"my_err.h"
#include<pthread.h>
int thread(void *arg)
{
printf("how to use pthread_create function %ld \n", pthread_self());
return 0;
}
void Pthread_create(pthread_t *th)
{
if(pthread_create(th, NULL,(void*)thread, NULL) != 0)
{
err_sys("create pthread failed");
exit(1);
}
return;
}
int main()
{
pthread_t th;
printf("main function pthread num is %ld \n", pthread_self());
Pthread_create(&th);//通过与下面的注释进行对比,可以清楚的了解什么是包裹函数
/*
if(pthread_create(&th, NULL,(void*)thread, NULL) != 0)
{
printf("create pthread failed\n");
exit(1);
}
*/
sleep(1);
return 0;
}
除了将首字母大写以外,还可以给函数名前缀e作为标志( epthread_create() )
包裹函数有助于检查那些错误返回值常被忽略的函数,如close和pthread_mutex_lock等。
不积小流无以成江河