说一个线程函数看起来像:
void *threadFunc(void *args)
{
if(args == NULL)
{
/*
* Let's assume that this case is a fatal error which
* cannot be recovered from.
*/
fprintf(stderr, "Yikes... demons avoided.\n");
exit(EXIT_FAILURE);
}
// Code to do stuff
return NULL; // Return value does not matter
}
注意:我这里的例子只是一个类比我精心设计,非常类似于我面临的真正问题。
PS:别担心,我的错误信息在现实中更具描述性。
我看到的情况是,这个致命错误被多于1个线程有时检测到。我发现有时候,当一个线程检测到这个错误并到达fprintf
时,它会被另一个线程抢占,它也检测到同样的错误,并在到达fprintf
时被抢占等等
我只是想知道如何处理这种特殊情况,这样当一个线程检测到这个致命错误时,它会立即关闭应用程序,以便其他线程在尝试关闭时不会干扰它申请失败。
我正在考虑在互斥锁中包含错误检测,如下所示:
void *threadFunc(void *args)
{
lockMutex(mutex);
if(args == NULL)
{
/*
* Let's assume that this case is a fatal error which
* cannot be recovered from.
*/
fprintf(stderr, "Yikes... demons avoided.\n");
exit(EXIT_FAILURE);
}
unlockMutex(mutex);
// Code to do stuff
return NULL; // Return value does not matter
}
这对我来说似乎不太优雅,因为如果检测到故障,则应用程序将退出而导致互斥锁被锁定。我知道操作系统应该释放所有资源,但这对我来说似乎并不是很好。
你能否提出另一种可能更好的方法呢?我的设计本身是否已损坏?
答案 0 :(得分:3)
bool deadmanWalking = false;
mutex deathMutex = INIT....
void cleanup()
{
lock(&deathMutex);
if (deadmanWalking)
{
unlock(&deathMutex);
return;
}
deadmanWalking = true;
// cleanup code
unlock(&deathMutex);
exit(EXIT_FAILURE);
}
//.........
if(args == NULL)
{
cleanup();
pthread_exit(...);
}
可以说最好的解决方案是从错误检测线程返回错误指示到任何启动它们并让它有序地取消剩余的线程和清理,而不是通过退出从它们下面删除底部。