簡體   English   中英

關鍵部分取消點

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM