0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核實(shí)際項(xiàng)目中的死鎖

麥辣雞腿堡 ? 來(lái)源:嵌入式Linux充電站 ? 作者:Vincent ? 2023-09-27 15:24 ? 次閱讀

實(shí)際項(xiàng)目中的死鎖

下面的例子要復(fù)雜一些,這是從實(shí)際項(xiàng)目中抽取出來(lái)的死鎖,更具有代表性。

#include < linux/init.h >
#include < linux/module.h >
#include < linux/kernel.h >
#include < linux/kthread.h >
#include < linux/freezer.h >
#include < linux/delay.h >


static DEFINE_MUTEX(mutex_a);
static struct delayed_work delay_task;
static void lockdep_timefunc(unsigned long);
static DEFINE_TIMER(lockdep_timer, lockdep_timefunc, 0, 0);

static void lockdep_timefunc(unsigned long dummy)
{
    schedule_delayed_work(&delay_task, 10);
    mod_timer(&lockdep_timer, jiffies + msecs_to_jiffies(100));
}

static void lockdep_test_work(struct work_struct *work)
{
    mutex_lock(&mutex_a);
    mdelay(300);//處理一些事情,這里用mdelay替代
    mutex_unlock(&mutex_a);
}

static int lockdep_thread(void *nothing)
{
    set_freezable();//清除當(dāng)前線程標(biāo)志flags中的PF_NOFREEZE位,表示當(dāng)前線程能進(jìn)入掛起或休眠狀態(tài)。
    set_user_nice(current, 0);
    while(!kthread_should_stop()){
        mdelay(500);//處理一些事情,這里用mdelay替代

        //遇到某些特殊情況,需要取消delay_task
        mutex_lock(&mutex_a);
        cancel_delayed_work_sync(&delay_task);
        mutex_unlock(&mutex_a);
    }

    return 0;
}


static int __init lockdep_test_init(void)
{
    printk("figo:my lockdep module initn");
    
   struct task_struct *lock_thread;

   /*創(chuàng)建一個(gè)線程來(lái)處理某些事情*/
   lock_thread = kthread_run(lockdep_thread, NULL, "lockdep_test");

   /*創(chuàng)建一個(gè)延遲的工作隊(duì)列*/
   INIT_DELAYED_WORK(&delay_task, lockdep_test_work);

   /*創(chuàng)建一個(gè)定時(shí)器來(lái)模擬某些異步事件,如中斷等*/
   lockdep_timer.expires = jiffies + msecs_to_jiffies(500);
   add_timer(&lockdep_timer);
 
    return 0;
}


static void __exit lockdep_test_exit(void)
{
  printk("goodbyen");
}

MODULE_LICENSE("GPL");
module_init(lockdep_test_init);
module_exit(lockdep_test_exit);

首先創(chuàng)建一個(gè)lockdep_thread內(nèi)核線程,用于周期性地處理某些事情,然后創(chuàng)建一個(gè)名為lockdep_test_worker的工作隊(duì)列來(lái)處理一些類似于中斷下半部的延遲操作,最后使用一個(gè)定時(shí)器來(lái)模擬某些異步事件(如中斷)。

在lockdep_thread內(nèi)核線程中,某些特殊情況下常常需要取消工作隊(duì)列。代碼中首先申請(qǐng)了一個(gè)mutex_a互斥鎖,然后調(diào)用cancel_delayed_work_sync()函數(shù)取消工作隊(duì)列。另外,定時(shí)器定時(shí)地調(diào)度工作隊(duì)列,并在回調(diào)函數(shù)lockdep_test_worker()函數(shù)中申請(qǐng)mutex_a互斥鎖。

接下來(lái)的函數(shù)調(diào)用棧顯示上述嘗試獲取mutex_a鎖的調(diào)用路徑。兩個(gè)路徑如下:

(1)內(nèi)核線程lockdep_thread首先成功獲取了mutex_a互斥鎖,然后調(diào)用cancel_delayed_work_sync()函數(shù)取消kworker。注意,cancel_delayed_work_sync()函數(shù)會(huì)調(diào)用flush操作并等待所有的kworker回調(diào)函數(shù)執(zhí)行完,然后才會(huì)調(diào)用mutex_unlock(&mutex_a)釋放該鎖。

圖片

(2)kworker回調(diào)函數(shù)lockdep_test_worker()首先會(huì)嘗試獲取mutex_a互斥鎖。 注意,剛才內(nèi)核線程lockdep_thread已經(jīng)獲取了mutex_a互斥鎖,并且一直在等待當(dāng)前kworker回調(diào)函數(shù)執(zhí)行完,所以死鎖發(fā)生了 。

圖片

下面是該死鎖場(chǎng)景的CPU調(diào)用關(guān)系:

CPU0                      CPU1
----------------------------------------------------------------
內(nèi)核線程lockdep_thread
lock(mutex_a)
   cancel_delayed_work_sync()
等待worker執(zhí)行完成     
                                  delay worker回調(diào)函數(shù)
                                  lock(mutex_a);嘗試獲取鎖
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1361

    瀏覽量

    40185
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11211

    瀏覽量

    208721
  • 死鎖
    +關(guān)注

    關(guān)注

    0

    文章

    25

    瀏覽量

    8059
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4284

    瀏覽量

    62325
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    FreeRTOS實(shí)時(shí)內(nèi)核實(shí)用指南

    FreeRTOS實(shí)時(shí)內(nèi)核實(shí)用指南
    發(fā)表于 09-18 08:02

    關(guān)于在實(shí)際項(xiàng)目中如何設(shè)計(jì)軟件實(shí)現(xiàn)延時(shí)?

    在現(xiàn)有的很多入門教程中,程序延時(shí)都是使用delay()函數(shù),就是讓CPU在空轉(zhuǎn),什么事情都不做。這個(gè)方法在演示實(shí)驗(yàn)或者一些簡(jiǎn)單的應(yīng)用還可以使用,但是應(yīng)用到實(shí)際的復(fù)雜項(xiàng)目中,就不行了。這會(huì)消耗大量
    發(fā)表于 12-12 16:14

    如何進(jìn)行嵌入式Linux內(nèi)核實(shí)時(shí)化研究?

    的設(shè)計(jì)原理和RTLinux類似,也是一個(gè)實(shí)時(shí)性應(yīng)用接口。那我們究竟該如何進(jìn)行嵌入式Linux內(nèi)核實(shí)時(shí)化研究?修改APIC中斷函數(shù),將APIC中斷和8254中斷排序,使得硬實(shí)時(shí)中斷的優(yōu)先級(jí)大于普通8254中斷。
    發(fā)表于 08-06 07:15

    如何搭建linux內(nèi)核實(shí)驗(yàn)平臺(tái)

    5.3實(shí)驗(yàn)內(nèi)容——?jiǎng)?chuàng)建Linux內(nèi)核和文件系統(tǒng)1.實(shí)驗(yàn)?zāi)康耐ㄟ^(guò)移植Linux內(nèi)核,熟悉嵌入式開(kāi)發(fā)環(huán)境的搭建和Linux
    發(fā)表于 12-16 08:08

    linux處理機(jī)調(diào)度與死鎖

    linux處理機(jī)調(diào)度與死鎖 掌握處理機(jī)的三級(jí)調(diào)度 掌握作業(yè)調(diào)度及進(jìn)程調(diào)度的概念 理解調(diào)度算法的評(píng)價(jià)準(zhǔn)則 掌握并靈活運(yùn)用常用的幾種作業(yè)調(diào)度、
    發(fā)表于 04-28 14:59 ?0次下載

    嵌入式Linux內(nèi)核實(shí)時(shí)性研究及改進(jìn)

    分析了嵌入式Linux 存在實(shí)時(shí)性缺陷的原因,從Linux 調(diào)度機(jī)制入手提出了可行的改進(jìn)方案,并詳細(xì)闡述了代碼實(shí)現(xiàn)。經(jīng)測(cè)試,改進(jìn)后的內(nèi)核實(shí)時(shí)性能得到很大提高。在嵌入式技術(shù)
    發(fā)表于 07-30 10:13 ?8次下載

    嵌入式內(nèi)核實(shí)

    嵌入式內(nèi)核實(shí)
    發(fā)表于 01-22 13:58 ?0次下載

    用crash工具分析Linux內(nèi)核死鎖的一次實(shí)戰(zhàn)分享

    內(nèi)核死鎖問(wèn)題一般是讀寫鎖(rw_semaphore)和互斥鎖(mutex)引起的,本文主要講如何通過(guò)ramdump+crash工具來(lái)分析這類死鎖問(wèn)題。
    的頭像 發(fā)表于 03-17 09:27 ?1.5w次閱讀
    用crash工具分析<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>死鎖</b>的一次實(shí)戰(zhàn)分享

    最硬核的Linux內(nèi)核文章

    內(nèi)核。 擁有超過(guò)1300萬(wàn)行的代碼,Linux內(nèi)核是世界上最大的開(kāi)源項(xiàng)目之一,但是內(nèi)核是什么,它用于什么? 02 什么是
    的頭像 發(fā)表于 10-19 17:46 ?2089次閱讀
    最硬核的<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>文章

    快速理解什么是Linux內(nèi)核以及Linux內(nèi)核的內(nèi)容

    01 前言 本文主要講解什么是Linux內(nèi)核,以及通過(guò)多張圖片展示Linux內(nèi)核的作用與功能,以便于讀者能快速理解什么是Linux
    的頭像 發(fā)表于 10-21 12:02 ?4247次閱讀
    快速理解什么是<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>以及<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>的內(nèi)容

    如何使用Linux內(nèi)核實(shí)現(xiàn)USB驅(qū)動(dòng)程序框架

    Linux內(nèi)核提供了完整的USB驅(qū)動(dòng)程序框架。USB總線采用樹(shù)形結(jié)構(gòu),在一條總線上只能有唯一的主機(jī)設(shè)備。 Linux內(nèi)核從主機(jī)和設(shè)備兩個(gè)角度觀察USB總線結(jié)構(gòu)。本節(jié)介紹
    發(fā)表于 11-06 17:59 ?20次下載
    如何使用<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核實(shí)</b>現(xiàn)USB驅(qū)動(dòng)程序框架

    Linux內(nèi)核的鏈表數(shù)據(jù)結(jié)構(gòu)

    Linux內(nèi)核實(shí)現(xiàn)了自己的鏈表數(shù)據(jù)結(jié)構(gòu),它的設(shè)計(jì)與傳統(tǒng)的方式不同,非常巧妙也很通用。
    的頭像 發(fā)表于 03-24 11:34 ?805次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>的鏈表數(shù)據(jù)結(jié)構(gòu)

    Linux內(nèi)核實(shí)現(xiàn)內(nèi)存管理的基本概念

    本文概述Linux內(nèi)核實(shí)現(xiàn)內(nèi)存管理的基本概念,在了解基本概念后,逐步展開(kāi)介紹實(shí)現(xiàn)內(nèi)存管理的相關(guān)技術(shù),后面會(huì)分多篇進(jìn)行介紹。
    發(fā)表于 06-23 11:56 ?783次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核實(shí)</b>現(xiàn)內(nèi)存管理的基本概念

    Linux內(nèi)核死鎖lockdep功能

    的編程思路,也不可能避免會(huì)發(fā)生死鎖。在Linux內(nèi)核中,常見(jiàn)的死鎖有如下兩種: 遞歸死鎖:如在中斷延遲操作中使用了鎖,和外面的鎖構(gòu)成了遞歸
    的頭像 發(fā)表于 09-27 15:13 ?663次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>死鎖</b>lockdep功能

    內(nèi)核實(shí)時(shí)操作系統(tǒng)的介紹

    內(nèi)核實(shí)時(shí)操作系統(tǒng)(Microkernel Real-Time Operating System, μRTOS)是一種專為實(shí)時(shí)設(shè)計(jì)的操作系統(tǒng)。它采用微內(nèi)核架構(gòu),以提高系統(tǒng)的可靠性、安全性和可擴(kuò)展性。以下是關(guān)于微內(nèi)核實(shí)時(shí)操作系統(tǒng)的
    的頭像 發(fā)表于 05-11 17:13 ?448次閱讀