簡體   English   中英

具有自旋鎖凍結功能的Linux內核線程

[英]Linux Kernel Threads with spinlock freeze

我有兩個內核線程,我試圖以替代方式從這兩個線程中打印。 我正在使用自旋鎖來同步這兩個線程。

 int kthread_1_function(void *data)
 {
     while(1)
     {
         spin_lock(&lock1);
         pr_alert("In Kernel Thread 1!!!\n");
         spin_unlock(&lock2);

        if(kthread_should_stop())
        {
            spin_unlock(&lock2);
            return 1;
        }
     }

     return 0;
 }

 int kthread_2_function(void *data)
 {
     while(1)
     {
         spin_lock(&lock2);
         pr_alert("In Kernel Thread 2!!!\n");
         spin_unlock(&lock1);

        if(kthread_should_stop())
        {
            spin_unlock(&lock1);
            return 2;
        }
      }

     return 0;
 }

在初始化模塊中,我創建了這些內核線程(kthread_run),並且cleanup_module停止了這些線程(kthread_stop)。

當我嘗試卸下模塊時,整個系統將掛起。 通過瀏覽內核源代碼,我可以看到spin_lock禁用了搶占,而kthread_stop嘗試喚醒應該被殺死的線程,並等待該線程退出並返回。 不知道是什么導致我的系統掛起。 從邏輯上講,它應該工作正常。

注意:初始化自旋鎖時,將lock1設置為UNLOCKED,將lock2設置為LOCKED。

您在這里遇到雙重解鎖問題。 linux中的Spinlock是使用稱為“ spinlock票務”的機制實現的。 如果您在此方案下兩次解鎖了自旋鎖,則每隔一次嘗試鎖定自旋鎖的操作都會導致線程永遠旋轉。
因此,問題在於if(kthread_should_stop())為true,您將鎖解鎖兩次,使所有其他試圖將其獲取的線程卡住了。

有關自旋鎖售票的更多信息: http : //en.wikipedia.org/wiki/Ticket_lock

另請注意,使用兩個鎖有些過時了。 我只是在兩個線程之間共享一個鎖。

好吧,您剛剛暗示了解決方案:在spinlock()中,搶占被禁用。 因此在spin_unlock()中將其重新啟用。

現在,問題是您將spin_unlocked到了與以前不同的變量上,並且在spin_unlocked上立即啟用了搶占功能,然后正常的CPU調度會將內核線程調度到另一個CPU繼續執行。

並且由於您已經創建了兩個kthread,因此每個kthread都可以由內核獨立調度。 因此,您將最終在另一個kthread上阻塞一個kthread,每個kthread運行在不同的CPU上。

自旋鎖的概念是由於多核的存在而產生的:在單核中,不需要自旋鎖:當只有一個CPU時,為什么CPU不做任何事情,而是旋轉鎖以等待它變為非空閑狀態?

最好先在自旋鎖上解鎖再鎖定另一個,因為每個自旋鎖都可以在不同的CPU本身上運行,因為CPU調度確實超出了您的控制范圍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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