繁体   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