我正在测试一个有关详细错误处理的想法,并希望让一个线程能够调用“getlasterror”#39;在需要处理错误时起作用。我使用便宜且简单的结构指针指针,但也使用pthread_t
id覆盖前一个条目(如果不需要或已处理错误信息)。
从stackoverflow帖子How do you query a pthread to see if it is still running?和How do I determine if a pthread is alive?,似乎使用pthread_kill
发送虚假信号可能不安全。是否真的没有替代机制来检查是否存在具有id的pthread?或者我可以禁用线程ID在运行时重用的能力吗? (我知道后者可能是安全问题......)
我之前没有写过任何代码,但是我在leafpad中粗略地掀起了我的计划下面的内容(所以忽略任何语法错误,如果有的话!)。兴趣点自然是动态清理,如果应用程序正在关闭则没有问题。任何其他替代想法也将受到欢迎:)
如果适用,这将是一个客户端/服务器程序,因此每个accept()
都会存在一个新线程。
struct error_info_structs
{
struct error_info** errs; // error_info struct with details
pthread_t** tids; // thread ids for each struct
uint32_t num; // number of error_info structs and thread ids
pthread_mutex_lock lock; // runtime locker
};
struct error_info_structs g_errs;
// assume we've done necessary initialization...
struct error_info*
get_last_runtime_error()
{
struct error_info* retval = NULL;
pthread_t tid = pthread_self();
pthread_mutex_lock(&g_errs.lock);
for ( uint32_t i = 0; i < g_errs.num; i++ )
{
if ( pthread_equal(g_errs.tids[i], tid) )
{
retval = g_errs.errs[i];
goto release_lock;
}
}
release_lock:
pthread_mutex_unlock(&g_errs.lock);
return retval;
}
void
raise_runtime_error(struct error_info* ei)
{
pthread_t tid = pthread_self();
pthread_mutex_lock(&g_errs.lock);
for ( uint32_t i = 0; i < g_errs.num; i++ )
{
if ( pthread_equal(g_errs.tids[i], tid) )
{
// replace existing
memcpy(&g_errs.errs[i], ei, sizeof(error_info));
goto release_lock;
}
/*
* Dynamic cleanup to lower risk of resource exhaustion.
* Do it here, where we actually allocate the memory, forcing
* this to be processed at least whenever a new thread raises
* an error.
*/
if ( pthread_kill(g_errs.tids[i], 0) != 0 )
{
// doesn't exist, free memory. safe to adjust counter.
free(g_errs.errs[i]);
free(g_errs.tids[i]);
g_errs.num--;
}
}
/*
* first error reported by this thread id. allocate memory to hold its
* details, eventually free when thread no longer exists.
*/
struct error_info* newei = malloc(sizeof(struct error_info));
if ( newei == NULL )
{
goto release_lock;
}
pthread_t* newt = malloc(sizeof(pthread_t));
if ( newt == NULL )
{
free(newei);
goto release_lock;
}
// realloc-bits omitted
g_errs.errs[g_errs.num] = newei;
g_errs.tids[g_errs.num] = newt;
g_errs.num++;
release_lock:
pthread_mutex_unlock(&g_errs.lock);
}
答案 0 :(得分:0)
...我可以禁用线程ID在运行时重用的功能吗?
不,你不能。