實(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)核
+關(guān)注
關(guān)注
3文章
1382瀏覽量
40427 -
Linux
+關(guān)注
關(guān)注
87文章
11345瀏覽量
210403 -
死鎖
+關(guān)注
關(guān)注
0文章
25瀏覽量
8087 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4346瀏覽量
62977
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
關(guān)于在實(shí)際項(xiàng)目中如何設(shè)計(jì)軟件實(shí)現(xiàn)延時(shí)?
如何進(jìn)行嵌入式Linux內(nèi)核實(shí)時(shí)化研究?
如何搭建linux內(nèi)核實(shí)驗(yàn)平臺(tái)
linux處理機(jī)調(diào)度與死鎖
嵌入式Linux內(nèi)核實(shí)時(shí)性研究及改進(jìn)
用crash工具分析Linux內(nèi)核死鎖的一次實(shí)戰(zhàn)分享
![用crash工具分析<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>死鎖</b>的一次實(shí)戰(zhàn)分享](https://file.elecfans.com/web1/M00/49/D1/o4YBAFqsb4GAE9uUAAAPV7QT8xs886.png)
最硬核的Linux內(nèi)核文章
![最硬核的<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>文章](https://file.elecfans.com/web1/M00/CA/4E/o4YBAF-NXzGAM7OiAAFTQFO35nY110.png)
快速理解什么是Linux內(nèi)核以及Linux內(nèi)核的內(nèi)容
![快速理解什么是<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)容](https://file.elecfans.com/web1/M00/CB/AB/pIYBAF-PsbaASbG3AABoasH5eFg888.png)
如何使用Linux內(nèi)核實(shí)現(xiàn)USB驅(qū)動(dòng)程序框架
![如何使用<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核實(shí)</b>現(xiàn)USB驅(qū)動(dòng)程序框架](https://file.elecfans.com/web1/M00/CE/DE/pIYBAF-lIPeADODWAAI0W5hPQOg995.png)
Linux內(nèi)核的鏈表數(shù)據(jù)結(jié)構(gòu)
![<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>的鏈表數(shù)據(jù)結(jié)構(gòu)](https://file1.elecfans.com/web2/M00/81/E7/wKgZomQdGgiAZILnAACKkPuzhSU888.jpg)
Linux內(nèi)核實(shí)現(xiàn)內(nèi)存管理的基本概念
![<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核實(shí)</b>現(xiàn)內(nèi)存管理的基本概念](https://file1.elecfans.com/web2/M00/89/F2/wKgaomSNLeCAPojBAAGc5x9Z-gc779.jpg)
Linux內(nèi)核死鎖lockdep功能
![<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>死鎖</b>lockdep功能](https://file1.elecfans.com/web2/M00/A6/53/wKgaomUT1P-AO5OKAAAL7WJJNAg682.jpg)
評(píng)論