在等待 pthread_mutex_lock 期间终止线程
Kill thread during it's waiting for pthread_mutex_lock
我在 Ubuntu 上用 C 编写代码。
我有超过 2 个这样的线程:
void * thread(void)
{
retry:
pthread_mutex_lock(&mutex);
//DO SOMETHING
pthread_mutex_unlock(&mutex);
goto retry;
}
所以我有 thread1,thread2,...,threadN。
有时 thread2,...,threadN 可以从 thread1 中用 pthread_cancel().
杀死
这个 pthread_cancel() 被插入到互斥体中,所以它在安全区被调用。
每次 thread1 在 threadK 上调用 pthread_cancel() 时,threadK 都在等待互斥锁,因此它调用了函数 pthread_mutex_lock()。
这件事会在我的程序中造成问题吗?
我的程序中有一个错误,我认为我遇到了死锁,但我不明白为什么。我觉得是这个原因。
在此先感谢大家。
如果可以避免,请不要使用线程取消。有很多问题和陷阱需要解决。
其中一个 class 问题与资源清理有关。尽管 POSIX 定义了一种注册清理处理程序的机制来解决这个问题,但需要大量艰苦的工作来确保所有资源——分配的内存、打开的文件、互斥锁和信号量、一般共享状态——都是正确的通过这些方式清理。一个线程很容易无法解锁它在取消时保持锁定的互斥量,从而使随后尝试无条件锁定它的每个线程都死锁。
另一个更微妙的 class 问题与线程实际可以取消的时间点有关。默认情况下,具有挂起取消信号的线程将在下一次到达取消点时终止,或者如果它已经在取消点处被阻塞。相当多的 POSIX 功能肯定是或可能是取消点,但不是全部。
特别是 pthread_mutex_lock()
is not a cancellation point。因此,如果您取消在 pthread_mutex_lock
中阻塞的线程,它不会立即被取消。原则上,它可能会成功锁定互斥锁,然后继续执行直到到达取消点,或者它可能 return 没有锁定互斥锁(使用非零 return 代码来指示错误的性质).两者都可能给你带来麻烦,但前者似乎特别容易让你陷入僵局。在实践中,pthread_mutex_lock()
被记录为 not return EINTR
,导致我期望前一个替代方案将被展示:取消请求不会导致阻塞在 pthread_mutex_lock()
中的线程在未获取互斥锁和 returning.
的情况下终止
我在 Ubuntu 上用 C 编写代码。 我有超过 2 个这样的线程:
void * thread(void)
{
retry:
pthread_mutex_lock(&mutex);
//DO SOMETHING
pthread_mutex_unlock(&mutex);
goto retry;
}
所以我有 thread1,thread2,...,threadN。 有时 thread2,...,threadN 可以从 thread1 中用 pthread_cancel().
杀死这个 pthread_cancel() 被插入到互斥体中,所以它在安全区被调用。
每次 thread1 在 threadK 上调用 pthread_cancel() 时,threadK 都在等待互斥锁,因此它调用了函数 pthread_mutex_lock()。
这件事会在我的程序中造成问题吗? 我的程序中有一个错误,我认为我遇到了死锁,但我不明白为什么。我觉得是这个原因。
在此先感谢大家。
如果可以避免,请不要使用线程取消。有很多问题和陷阱需要解决。
其中一个 class 问题与资源清理有关。尽管 POSIX 定义了一种注册清理处理程序的机制来解决这个问题,但需要大量艰苦的工作来确保所有资源——分配的内存、打开的文件、互斥锁和信号量、一般共享状态——都是正确的通过这些方式清理。一个线程很容易无法解锁它在取消时保持锁定的互斥量,从而使随后尝试无条件锁定它的每个线程都死锁。
另一个更微妙的 class 问题与线程实际可以取消的时间点有关。默认情况下,具有挂起取消信号的线程将在下一次到达取消点时终止,或者如果它已经在取消点处被阻塞。相当多的 POSIX 功能肯定是或可能是取消点,但不是全部。
特别是 pthread_mutex_lock()
is not a cancellation point。因此,如果您取消在 pthread_mutex_lock
中阻塞的线程,它不会立即被取消。原则上,它可能会成功锁定互斥锁,然后继续执行直到到达取消点,或者它可能 return 没有锁定互斥锁(使用非零 return 代码来指示错误的性质).两者都可能给你带来麻烦,但前者似乎特别容易让你陷入僵局。在实践中,pthread_mutex_lock()
被记录为 not return EINTR
,导致我期望前一个替代方案将被展示:取消请求不会导致阻塞在 pthread_mutex_lock()
中的线程在未获取互斥锁和 returning.