我想要完成的是主线程首先在工作线程上尝试正常的延迟取消(执行代表我的目的是黑盒子),然后如果线程在超时后仍在运行({{ 1}}),我想做异步取消。我遇到的问题是pthread_timedjoin_np()
仅用于调用线程。是否有一些解决方法或黑客可以让我这样做?我想避免使用信号,至少在Linux下,似乎异步取消仍然会执行线程对象的C ++析构函数,这对我来说非常重要。
答案 0 :(得分:2)
在某些情况下,当pthread_setcanceltype()
必须实际取消时(请参阅下面的来源)。所以,这是一个原因,为什么没有pthread_setcanceltype_for_thread()
。实际的取消类型是pthread结构中的字段,必须以原子方式更改。
__pthread_setcanceltype (type, oldtype)
int type;
int *oldtype;
{
volatile struct pthread *self;
self = THREAD_SELF;
int oldval = THREAD_GETMEM (self, cancelhandling);
while (1)
{
int newval = (type == PTHREAD_CANCEL_ASYNCHRONOUS
? oldval | CANCELTYPE_BITMASK
: oldval & ~CANCELTYPE_BITMASK);
/* Store the old value. */
if (oldtype != NULL)
*oldtype = ((oldval & CANCELTYPE_BITMASK)
? PTHREAD_CANCEL_ASYNCHRONOUS : PTHREAD_CANCEL_DEFERRED);
/* Update the cancel handling word. This has to be done
atomically since other bits could be modified as well. */
int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
oldval);
if (__builtin_expect (curval == oldval, 1))
{
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
{
THREAD_SETMEM (self, result, PTHREAD_CANCELED);
__do_cancel (); // HERE THE CANCELLING
}
break;
}
/* Prepare for the next round. */
oldval = curval;
}
return 0;
}
strong_alias (__pthread_setcanceltype, pthread_setcanceltype)
如果你非常需要在外部更改canceltype,你可以破解库并直接设置字段。
PS:for NPTL(Linux上glibc中pthreads的当前实现)
查看如何从int pthread_t获取struct pthread
的最简单方法是... pthread_join:
pthread_join (pthread_t threadid, thread_return)
{
struct pthread *pd = (struct pthread *) threadid;