如果一个公司开发流程规范,注重代码的积累,基础库肯定是和承载的上层业务逻辑分开的,那么应该如何处理基础库的内部错误信息,以反馈给上层的业务逻辑呢?其中有一个原则要遵守:方便上层的调试,及发生错误时的定位。解决这样问题的一个思路是:其它库是怎么做的?聪明的你肯定想到了errno,及
GetLastError。
对,使用线程专有存储。下面是linux下的示例
1
#include <stdio.h>
2
#include <string.h>
3
#include <pthread.h>
4
#include <unistd.h>
5
6
pthread_key_t key;
7
8
struct SError
9

{
10
int code;
11
char msg[512];
12
};
13
14
void SetErrInfo(const int nCode,const char* pMsg)
15

{
16
SError* pErr = (SError*)pthread_getspecific(key);
17
if(pErr == NULL)
18
{//该线程还没有分配错误信息的内存
19
pErr = new SError();
20
pErr->code = nCode;
21
strcpy(pErr->msg,pMsg);
22
pthread_setspecific(key,(void*)pErr);
23
}
24
else
25
{
26
pErr->code = nCode;
27
strcpy(pErr->msg,pMsg);
28
}
29
return;
30
}
31
const char* GetErrMsg()
32

{
33
SError* pErr = (SError*)pthread_getspecific(key);
34
if(pErr == NULL)
35
return NULL;
36
else
37
return pErr->msg;
38
}
39
const int GetErrCode()
40

{
41
SError* pErr = (SError*)pthread_getspecific(key);
42
if(pErr == NULL)
43
return 0;
44
else
45
return pErr->code;
46
}
47
48
void echomsg(SError* t)
49

{
50
printf("destructor excuted in thread %u,code = %d,msg = %s\n",pthread_self(),t->code,t->msg);
51
delete t;//前面传入的是内存的地址。所以可以delete
52
}
53
void * child1(void *arg)
54

{
55
int tid=pthread_self();
56
printf("thread %u enter\n",tid);
57
SetErrInfo(0,"OK");
58
sleep(2);
59
printf("thread= %u,code = %d , msg = %s\n",tid,GetErrCode(),GetErrMsg());
60
sleep(5);
61
}
62
63
void * child2(void *arg)
64

{
65
int tid=pthread_self();
66
printf("thread %u enter\n",tid);
67
SetErrInfo(1,"bad");
68
sleep(2);
69
printf("thread= %u,code = %d , msg = %s\n",tid,GetErrCode(),GetErrMsg());
70
sleep(2);
71
SetErrInfo(2,"bad2");
72
printf("thread= %u,code = %d , msg = %s\n",tid,GetErrCode(),GetErrMsg());
73
}
74
75
int main(void)
76

{
77
int tid1,tid2;
78
printf("hello\n");
79
pthread_key_create(&key,(void (*)(void*))echomsg);
80
pthread_create((pthread_t *)&tid1,NULL,child1,NULL);
81
pthread_create((pthread_t *)&tid2,NULL,child2,NULL);
82
sleep(10);
83
pthread_key_delete(key);
84
printf("main thread exit\n");
85
return 0;
86
}
1.开发中可以重载多个SetErrInfo,实现sprintf的格式化字符串功能;
2.基础库本身只需导出GetErrMsg和GetErrCode两个接口,比单纯用返回值来判断错误灵活的多
3.windows下可用Tls*系列api实现