等待条件变量时,取消点清除时是否需要解锁互斥锁?

问题描述 投票:0回答:1

在pthread库中有取消点的概念。 pthread取消点可能会中止大多数可能阻止执行时间较长(或等待某些资源...)的系统功能。

[猜想某些数据受条件变量保护,这些条件变量在线程中执行,就像下面的伪代码一样。该线程具有安装程序清除过程,以防对此线程发出取消请求。

THREAD_CLEANUP_PROC {
    UNLOCK(mutex) // Is this unlock required?
}

THREAD_PROC {
    SET THREAD_CLEANUP = THREAD_CLEANUP_PROC
    LOOP {
        LOCK(mutex)
        WHILE (condition == false) {
            condition.WAIT(mutex) // wait interrupted, cancel point is called
        }
        // ... we have the lock
        UNLOCK(mutex)
        condition.NOTIFY_ALL()

        read(descriptor); // wait for some data on a file descriptor while lock is not acquired
    }
}

如果有人在等待条件变量的同时取消线程(pthread_cancel()),则有关pthread_cond_wait的文档说该线程在获取锁的过程中被解除阻塞,并在线程结束之前开始执行清除处理程序。

我是不是真的由清理处理程序负责解锁该锁(互斥锁?如果像我的示例一样,还有另一种阻塞方法,例如read,它在等待数据时阻塞但没有获取锁,该怎么办?在这种情况下,read也将被解锁,并且像以前一样调用清除处理程序。仅这次,清理处理程序不得解锁互斥锁。我对么。如果是这样,处理这种情况的最佳方法是什么?是否有应遵循的共同概念?

c pthreads locking condition-variable code-cleanup
1个回答
0
投票

线程取消是混乱的。一般来说,您不应该这样做。

在pthread库中有取消点的概念。

[大多数可能阻止执行时间更长的系统功能(或等待某些资源...)可能会被pthread取消点中止。

不完全是。许多功能,例如您描述are取消点。具有“延迟”取消类型的线程在调用作为取消点的函数(如果当前可取消并且有取消请求待处理)时将中止。这并不意味着可以通过取消线程来中断此类功能。具有“异步”取消功能的线程可以随时或多或少地被取消,包括在阻止长时间运行的任务时,但是在这种情况下取​​消点是无关紧要的。

如果有人在等待条件变量的同时取消线程(pthread_cancel()),则有关pthread_cond_wait的文档说该线程在获取锁的过程中被解除阻塞,并在线程结束之前开始执行清除处理程序。

是,只要线程具有“延迟”取消类型。

我是不是真的清理程序现在负责解锁该锁(互斥锁?

是。在这种情况下,线程在开始取消过程时会将互斥锁保持锁定状态。如果它在终止之前没有解锁互斥锁,那么至少您会感到麻烦。某些类型的互斥锁(受pthread支持)可以提供一种从这种情况中恢复的方法,但是您最好避免这种情况。

如果-在我的示例中-还有另一种阻止方法,例如在等待数据但没有获取锁的情况下阻止读取的读取?在这种情况下,读取也会被解除阻塞,并且像以前一样调用清除处理程序。仅这次,清理处理程序不得解锁互斥锁。我正确吗?

同样,互斥量有多种类型,并且情况可能会因您使用的情况而异,但是到目前为止,最佳选择是仔细避免任何线程尝试解锁未锁定的互斥量。

如果是这样,处理这种情况的最佳方法是什么?

处理这种情况的最佳方法是首先避免这种情况。不要使用线程取消,尤其是对于容易出现这种问题的线程,这实际上是很常见的。

相反,请谨慎地编写多线程程序,以为您提供及时关闭线程或整个程序的替代方法。有很多这样的技术,超出了我在SO答案中可以合理概括的范围。

© www.soinside.com 2019 - 2024. All rights reserved.