[英]Cancellation points in Critical Section
我已經使用 pthread 實現了一個多線程應用程序。 在這個應用程序中有兩個線程:
為了避免在訪問端口(串行或分接)之前出現數據競爭問題,我使用了pthread_mutex_t 。 在https://man7.org/linux/man-pages/man7/pthreads.7.html我讀到read()和write()是取消點,也就是說,它們是線程可能被取消的點。
偽代碼示例:
pthread_mutex_t serial_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t tap_mutex = PTHREAD_MUTEX_INITIALIZER;
atomic_bool continue = true;
//T1
void* run(void* vargp)
{
int poll_timeout = 1000;
while (continue)
{
int poll_result = poll(&tap_fd, 1, poll_timeout);
if (poll_result != -1 && poll_result != 0)
{
if (tap_fd.revents & POLLIN)
{
pthread_mutex_lock(&tap_mutex);
int tap_len = read(tap, tap_buffer, sizeof(tap_buffer));
pthread_mutex_unlock(&tap_mutex);
if(tap_len >= MIN_SIZE)
{
/*
In reality, the contents of the tap buffer are preprocessed and the
contents of another buffer are written to the serial
*/
pthread_mutex_lock(&serial_mutex);
int r = write(serial, tap_buffer, tap_len);
pthread_mutex_unlock(&serial_mutex);
}
}
}
}
//T2 is completely analogous to the previous one
由於讀寫都是在臨界區執行的,如果線程被取消,互斥鎖會自動釋放嗎? 如果沒有,我如何保證相關互斥鎖的釋放?
如果要取消線程,互斥鎖會自動釋放嗎?
不。
如果沒有,我如何保證相關互斥鎖的釋放?
最好的方法是遵循pthread_cancel()
的第一條規則:永遠不要調用pthread_cancel()
。 真的,不要取消線程。 這是個壞消息。
您可以做的另一件事是在關鍵部分之前和之后使用pthread_setcancelstate()
來禁用線程取消。
而且,POSIX 確實具有處理線程取消清理的功能。 您可以使用pthread_cleanup_push()
注冊回調以執行所需的清理,並在關鍵部分之后使用pthread_cleanup_pop()
再次將其刪除。 為了使這種機制充分保護您,線程的取消類型必須(始終)是“延遲的”,並且您必須非常小心地始終如一地管理清理處理程序堆棧。 如果這聽起來像很多工作,那是因為它是。 請參閱pthread_cancel()
的第一條規則。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.