91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

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

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

Linux 自旋鎖spinlock

工程師 ? 來(lái)源:嵌入式客棧 ? 作者:嵌入式客棧 ? 2020-09-11 14:36 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

背景

由于在多處理器環(huán)境中某些資源的有限性,有時(shí)需要互斥訪問(wèn)(mutual exclusion),這時(shí)候就需要引入鎖的概念,只有獲取了鎖的任務(wù)才能夠?qū)Y源進(jìn)行訪問(wèn),由于多線程的核心是CPU的時(shí)間分片,所以同一時(shí)刻只能有一個(gè)任務(wù)獲取到鎖。

內(nèi)核當(dāng)發(fā)生訪問(wèn)資源沖突的時(shí)候,通常有兩種處理方式:

一個(gè)是原地等待

一個(gè)是掛起當(dāng)前進(jìn)程,調(diào)度其他進(jìn)程執(zhí)行(睡眠)

自旋鎖

Spinlock 是內(nèi)核中提供的一種比較常見(jiàn)的鎖機(jī)制,自旋鎖是“原地等待”的方式解決資源沖突的。即,一個(gè)線程獲取了一個(gè)自旋鎖后,另外一個(gè)線程期望獲取該自旋鎖,獲取不到,只能夠原地“打轉(zhuǎn)”(忙等待)。

由于自旋鎖的這個(gè)忙等待的特性,注定了它使用場(chǎng)景上的限制 —— 自旋鎖不應(yīng)該被長(zhǎng)時(shí)間的持有(消耗 CPU 資源)。

自旋鎖的優(yōu)點(diǎn)

自旋鎖不會(huì)使線程狀態(tài)發(fā)生切換,一直處于用戶(hù)態(tài),即線程一直都是active的;不會(huì)使線程進(jìn)入阻塞狀態(tài),減少了不必要的上下文切換,執(zhí)行速度快。

非自旋鎖在獲取不到鎖的時(shí)候會(huì)進(jìn)入阻塞狀態(tài),從而進(jìn)入內(nèi)核態(tài),當(dāng)獲取到鎖的時(shí)候需要從內(nèi)核態(tài)恢復(fù),需要線程上下文切換。(線程被阻塞后便進(jìn)入內(nèi)核(Linux)調(diào)度狀態(tài),這個(gè)會(huì)導(dǎo)致系統(tǒng)在用戶(hù)態(tài)與內(nèi)核態(tài)之間來(lái)回切換,嚴(yán)重影響鎖的性能)。

自旋鎖的使用

在linux kernel的實(shí)現(xiàn)中,經(jīng)常會(huì)遇到這樣的場(chǎng)景:共享數(shù)據(jù)被中斷上下文和進(jìn)程上下文訪問(wèn),該如何保護(hù)呢?

如果只有進(jìn)程上下文的訪問(wèn),那么可以考慮使用semaphore或者mutex的鎖機(jī)制,但是現(xiàn)在中斷上下文也摻和進(jìn)來(lái),那些可以導(dǎo)致睡眠的lock就不能使用了,這時(shí)候,可以考慮使用spin lock。

在中斷上下文,是不允許睡眠的,所以,這里需要的是一個(gè)不會(huì)導(dǎo)致睡眠的鎖——spinlock。

換言之,中斷上下文要用鎖,首選 spinlock。

使用自旋鎖,有兩種方式定義一個(gè)鎖:

動(dòng)態(tài)的:

spinlock_t lock;spin_lock_init (&lock);

靜態(tài)的:

DEFINE_SPINLOCK(lock);

使用步驟

spinlock的使用很簡(jiǎn)單:

我們要訪問(wèn)臨界資源需要首先申請(qǐng)自旋鎖;

獲取不到鎖就自旋,如果能獲得鎖就進(jìn)入臨界區(qū);

當(dāng)自旋鎖釋放后,自旋在這個(gè)鎖的任務(wù)即可獲得鎖并進(jìn)入臨界區(qū),退出臨界區(qū)的任務(wù)必須釋放自旋鎖。

使用實(shí)例

static spinlock_t lock;static int flage = 1;spin_lock_init(&lock);static int hello_open (struct inode *inode, struct file *filep){ spin_lock(&lock); if(flage !=1) { spin_unlock(&lock); return -EBUSY; } flage =0; spin_unlock(&lock); return 0;}static int hello_release (struct inode *inode, struct file *filep){ flage = 1; return 0;}

補(bǔ)充

中斷上下文不能睡眠的原因是:

中斷處理的時(shí)候,不應(yīng)該發(fā)生進(jìn)程切換,因?yàn)樵谥袛郼ontext中,唯一能打斷當(dāng)前中斷handler的只有更高優(yōu)先級(jí)的中斷,它不會(huì)被進(jìn)程打斷,如果在 中斷context中休眠,則沒(méi)有辦法喚醒它,因?yàn)樗械膚ake_up_xxx都是針對(duì)某個(gè)進(jìn)程而言的,而在中斷context中,沒(méi)有進(jìn)程的概念,沒(méi) 有一個(gè)task_struct(這點(diǎn)對(duì)于softirq和tasklet一樣),因此真的休眠了,比如調(diào)用了會(huì)導(dǎo)致block的例程,內(nèi)核幾乎肯定會(huì)死。

schedule()在切換進(jìn)程時(shí),保存當(dāng)前的進(jìn)程上下文(CPU寄存器的值、進(jìn)程的狀態(tài)以及堆棧中的內(nèi)容),以便以后恢復(fù)此進(jìn)程運(yùn)行。中斷發(fā)生后,內(nèi)核會(huì)先保存當(dāng)前被中斷的進(jìn)程上下文(在調(diào)用中斷處理程序后恢復(fù));

但在中斷處理程序里,CPU寄存器的值肯定已經(jīng)變化了吧(最重要的程序計(jì)數(shù)器PC、堆棧SP等),如果此時(shí)因?yàn)樗呋蜃枞僮髡{(diào)用了schedule(),則保存的進(jìn)程上下文就不是當(dāng)前的進(jìn)程context了。所以不可以在中斷處理程序中調(diào)用schedule()。

內(nèi)核中schedule()函數(shù)本身在進(jìn)來(lái)的時(shí)候判斷是否處于中斷上下文:

if(unlikely(in_interrupt())) BUG();

因此,強(qiáng)行調(diào)用schedule()的結(jié)果就是內(nèi)核BUG。

中斷handler會(huì)使用被中斷的進(jìn)程內(nèi)核堆棧,但不會(huì)對(duì)它有任何影響,因?yàn)閔andler使用完后會(huì)完全清除它使用的那部分堆棧,恢復(fù)被中斷前的原貌。

處于中斷context時(shí)候,內(nèi)核是不可搶占的。因此,如果休眠,則內(nèi)核一定掛起。

自旋鎖的死鎖

自旋鎖不可遞歸,自己等待自己已經(jīng)獲取的鎖,會(huì)導(dǎo)致死鎖。

自旋鎖可以在中斷上下文中使用,但是試想一個(gè)場(chǎng)景:一個(gè)線程獲取了一個(gè)鎖,但是被中斷處理程序打斷,中斷處理程序也獲取了這個(gè)鎖(但是之前已經(jīng)被鎖住了,無(wú)法獲取到,只能自旋),中斷無(wú)法退出,導(dǎo)致線程中后面釋放鎖的代碼無(wú)法被執(zhí)行,導(dǎo)致死鎖。(如果確認(rèn)中斷中不會(huì)訪問(wèn)和線程中同一個(gè)鎖,其實(shí)無(wú)所謂)。

一、考慮下面的場(chǎng)景(內(nèi)核搶占場(chǎng)景):

(1)進(jìn)程A在某個(gè)系統(tǒng)調(diào)用過(guò)程中訪問(wèn)了共享資源 R

(2)進(jìn)程B在某個(gè)系統(tǒng)調(diào)用過(guò)程中也訪問(wèn)了共享資源 R

會(huì)不會(huì)造成沖突呢?

假設(shè)在A訪問(wèn)共享資源R的過(guò)程中發(fā)生了中斷,中斷喚醒了沉睡中的,優(yōu)先級(jí)更高的B,在中斷返回現(xiàn)場(chǎng)的時(shí)候,發(fā)生進(jìn)程切換,B啟動(dòng)執(zhí)行,并通過(guò)系統(tǒng)調(diào)用訪問(wèn)了R,如果沒(méi)有鎖保護(hù),則會(huì)出現(xiàn)兩個(gè)thread進(jìn)入臨界區(qū),導(dǎo)致程序執(zhí)行不正確。OK,我們加上spin lock看看如何:A在進(jìn)入臨界區(qū)之前獲取了spin lock,同樣的,在A訪問(wèn)共享資源R的過(guò)程中發(fā)生了中斷,中斷喚醒了沉睡中的,優(yōu)先級(jí)更高的B,B在訪問(wèn)臨界區(qū)之前仍然會(huì)試圖獲取spin lock,這時(shí)候由于A進(jìn)程持有spin lock而導(dǎo)致B進(jìn)程進(jìn)入了永久的spin……怎么破?linux的kernel很簡(jiǎn)單,在A進(jìn)程獲取spin lock的時(shí)候,禁止本CPU上的搶占(上面的永久spin的場(chǎng)合僅僅在本CPU的進(jìn)程搶占本CPU的當(dāng)前進(jìn)程這樣的場(chǎng)景中發(fā)生)。如果A和B運(yùn)行在不同的CPU上,那么情況會(huì)簡(jiǎn)單一些:A進(jìn)程雖然持有spin lock而導(dǎo)致B進(jìn)程進(jìn)入spin狀態(tài),不過(guò)由于運(yùn)行在不同的CPU上,A進(jìn)程會(huì)持續(xù)執(zhí)行并會(huì)很快釋放spin lock,解除B進(jìn)程的spin狀態(tài)。

二、再考慮下面的場(chǎng)景(中斷上下文場(chǎng)景):

運(yùn)行在CPU0上的進(jìn)程A在某個(gè)系統(tǒng)調(diào)用過(guò)程中訪問(wèn)了共享資源 R

運(yùn)行在CPU1上的進(jìn)程B在某個(gè)系統(tǒng)調(diào)用過(guò)程中也訪問(wèn)了共享資源 R

外設(shè)P的中斷handler中也會(huì)訪問(wèn)共享資源 R

在這樣的場(chǎng)景下,使用spin lock可以保護(hù)訪問(wèn)共享資源R的臨界區(qū)嗎?

我們假設(shè)CPU0上的進(jìn)程A持有spin lock進(jìn)入臨界區(qū),這時(shí)候,外設(shè)P發(fā)生了中斷事件,并且調(diào)度到了CPU1上執(zhí)行,看起來(lái)沒(méi)有什么問(wèn)題,執(zhí)行在CPU1上的handler會(huì)稍微等待一會(huì)CPU0上的進(jìn)程A,等它立刻臨界區(qū)就會(huì)釋放spin lock的,但是,如果外設(shè)P的中斷事件被調(diào)度到了CPU0上執(zhí)行會(huì)怎么樣?CPU0上的進(jìn)程A在持有spin lock的狀態(tài)下被中斷上下文搶占,而搶占它的CPU0上的handler在進(jìn)入臨界區(qū)之前仍然會(huì)試圖獲取spin lock,悲劇發(fā)生了,CPU0上的P外設(shè)的中斷handler永遠(yuǎn)的進(jìn)入spin狀態(tài),這時(shí)候,CPU1上的進(jìn)程B也不可避免在試圖持有spin lock的時(shí)候失敗而導(dǎo)致進(jìn)入spin狀態(tài)。為了解決這樣的問(wèn)題,linux kernel采用了這樣的辦法:如果涉及到中斷上下文的訪問(wèn),spin lock需要和禁止本 CPU 上的中斷聯(lián)合使用。

三、再考慮下面的場(chǎng)景(底半部場(chǎng)景)

linux kernel中提供了豐富的bottom half的機(jī)制,雖然同屬中斷上下文,不過(guò)還是稍有不同。我們可以把上面的場(chǎng)景簡(jiǎn)單修改一下:外設(shè)P不是中斷handler中訪問(wèn)共享資源R,而是在的bottom half中訪問(wèn)。使用spin lock+禁止本地中斷當(dāng)然是可以達(dá)到保護(hù)共享資源的效果,但是使用牛刀來(lái)殺雞似乎有點(diǎn)小題大做,這時(shí)候disable bottom half就可以了。

四、中斷上下文之間的競(jìng)爭(zhēng)

同一種中斷handler之間在uni core和multi core上都不會(huì)并行執(zhí)行,這是linux kernel的特性。如果不同中斷handler需要使用spin lock保護(hù)共享資源,對(duì)于新的內(nèi)核(不區(qū)分fast handler和slow handler),所有handler都是關(guān)閉中斷的,因此使用spin lock不需要關(guān)閉中斷的配合。bottom half又分成softirq和tasklet,同一種softirq會(huì)在不同的CPU上并發(fā)執(zhí)行,因此如果某個(gè)驅(qū)動(dòng)中的softirq的handler中會(huì)訪問(wèn)某個(gè)全局變量,對(duì)該全局變量是需要使用spin lock保護(hù)的,不用配合disable CPU中斷或者bottom half。tasklet更簡(jiǎn)單,因?yàn)橥环Ntasklet不會(huì)多個(gè)CPU上并發(fā)。

自旋鎖的實(shí)現(xiàn)原理

數(shù)據(jù)結(jié)構(gòu)

首先定義一個(gè) spinlock_t 的數(shù)據(jù)類(lèi)型,其本質(zhì)上是一個(gè)整數(shù)值(對(duì)該數(shù)值的操作需要保證原子性),該數(shù)值表示spin lock是否可用。初始化的時(shí)候被設(shè)定為1。當(dāng)thread想要持有鎖的時(shí)候調(diào)用spin_lock函數(shù),該函數(shù)將spin lock那個(gè)整數(shù)值減去1,然后進(jìn)行判斷,如果等于0,表示可以獲取spin lock,如果是負(fù)數(shù),則說(shuō)明其他thread的持有該鎖,本thread需要spin。

內(nèi)核中的spinlock_t的數(shù)據(jù)類(lèi)型定義如下:

typedef struct spinlock { struct raw_spinlock rlock; } spinlock_t;typedef struct raw_spinlock { arch_spinlock_t raw_lock;} raw_spinlock_t;

通用(適用于各種arch)的spin lock使用spinlock_t這樣的type name,各種arch定義自己的struct raw_spinlock。聽(tīng)起來(lái)不錯(cuò)的主意和命名方式,直到linux realtime tree(PREEMPT_RT)提出對(duì)spinlock的挑戰(zhàn)。

spin lock的命名規(guī)范定義如下:

spinlock,在rt linux(配置了PREEMPT_RT)的時(shí)候可能會(huì)被搶占(實(shí)際底層可能是使用支持PI(優(yōu)先級(jí)翻轉(zhuǎn))的mutext)。

raw_spinlock,即便是配置了PREEMPT_RT也要頑強(qiáng)的spin

arch_spinlock,spin lock是和architecture相關(guān)的,

ARM 結(jié)構(gòu)體系 arch_spin_lock 接口實(shí)現(xiàn)

加鎖

同樣的,這里也只是選擇一個(gè)典型的API來(lái)分析,其他的大家可以自行學(xué)習(xí)。我們選擇的是 arch_spin_lock,其ARM32的代碼如下:

static inline void arch_spin_lock(arch_spinlock_t *lock){ unsigned long tmp; u32 newval; arch_spinlock_t lockval; prefetchw(&lock-》slock);---------(0) __asm__ __volatile__(“1: ldrex %0, [%3]\n”---------(1)“ add %1, %0, %4\n” ----------(2)“ strex %2, %1,[%3]\n”---------(3)“ teq %2, #0\n”-------------(4)“ bne 1b” : “=&r” (lockval), “=&r” (newval), “=&r” (tmp) : “r” (&lock-》slock), “I” (1 《《 TICKET_SHIFT) : “cc”); while (lockval.tickets.next != lockval.tickets.owner) {----(5) wfe();------------(6) lockval.tickets.owner = ACCESS_ONCE(lock-》tickets.owner);----(7) } smp_mb();-----------(8)}

(0)和preloading cache相關(guān)的操作,主要是為了性能考慮(1)lockval = lock-》slock (如果lock-》slock沒(méi)有被其他處理器獨(dú)占,則標(biāo)記當(dāng)前執(zhí)行處理器對(duì)lock-》slock地址的獨(dú)占訪問(wèn);否則不影響)(2)newval = lockval + (1 《《 TICKET_SHIFT)(3)strex tmp, newval, [&lock-》slock] (如果當(dāng)前執(zhí)行處理器沒(méi)有獨(dú)占lock-》slock地址的訪問(wèn),不進(jìn)行存儲(chǔ),返回1給temp;如果當(dāng)前處理器已經(jīng)獨(dú)占lock-》slock內(nèi)存訪問(wèn),則對(duì)內(nèi)存進(jìn)行寫(xiě),返回0給temp,清除獨(dú)占標(biāo)記) lock-》tickets.next = lock-》tickets.next + 1(4)檢查是否寫(xiě)入成功 lockval.tickets.next(5)初始化時(shí)lock-》tickets.owner、lock-》tickets.next都為0,假設(shè)第一次執(zhí)行arch_spin_lock,lockval = *lock,lock-》tickets.next++,lockval.tickets.next 等于 lockval.tickets.owner,獲取到自旋鎖;自旋鎖未釋放,第二次執(zhí)行的時(shí)候,lock-》tickets.owner = 0, lock-》tickets.next = 1,拷貝到lockval后,lockval.tickets.next != lockval.tickets.owner,會(huì)執(zhí)行wfe等待被自旋鎖釋放被喚醒,自旋鎖釋放時(shí)會(huì)執(zhí)行 lock-》tickets.owner++,lockval.tickets.owner重新賦值(6)暫時(shí)中斷掛起執(zhí)行。如果當(dāng)前spin lock的狀態(tài)是locked,那么調(diào)用wfe進(jìn)入等待狀態(tài)。更具體的細(xì)節(jié)請(qǐng)參考ARM WFI和WFE指令中的描述。(7)其他的CPU喚醒了本cpu的執(zhí)行,說(shuō)明owner發(fā)生了變化,該新的own賦給lockval,然后繼續(xù)判斷spin lock的狀態(tài),也就是回到step 5。(8)memory barrier的操作,具體可以參考memory barrier中的描述。

釋放鎖

static inline void arch_spin_unlock(arch_spinlock_t *lock){ smp_mb(); lock-》tickets.owner++; ---------------------- (0) dsb_sev(); ---------------------------------- (1)}

(0)lock-》tickets.owner增加1,下一個(gè)被喚醒的處理器會(huì)檢查該值是否與自己的lockval.tickets.next相等,lock-》tickets.owner代表可以獲取的自旋鎖的處理器,lock-》tickets.next你一個(gè)可以獲取的自旋鎖的owner;處理器獲取自旋鎖時(shí),會(huì)先讀取lock-》tickets.next用于與lock-》tickets.owner比較并且對(duì)lock-》tickets.next加1,下一個(gè)處理器獲取到的lock-》tickets.next就與當(dāng)前處理器不一致了,兩個(gè)處理器都與lock-》tickets.owner比較,肯定只有一個(gè)處理器會(huì)相等,自旋鎖釋放時(shí)時(shí)對(duì)lock-》tickets.owner加1計(jì)算,因此,先申請(qǐng)自旋鎖多處理器lock-》tickets.next值更新,自然先獲取到自旋鎖

(1)執(zhí)行sev指令,喚醒wfe等待的處理器

自旋鎖導(dǎo)致死鎖實(shí)例

死鎖的2種情況

1)擁有自旋鎖的進(jìn)程A在內(nèi)核態(tài)阻塞了,內(nèi)核調(diào)度B進(jìn)程,碰巧B進(jìn)程也要獲得自旋鎖,此時(shí)B只能自旋轉(zhuǎn)。而此時(shí)搶占已經(jīng)關(guān)閉,不會(huì)調(diào)度A進(jìn)程了,B永遠(yuǎn)自旋,產(chǎn)生死鎖。

2)進(jìn)程A擁有自旋鎖,中斷到來(lái),CPU執(zhí)行中斷函數(shù),中斷處理函數(shù),中斷處理函數(shù)需要獲得自旋鎖,訪問(wèn)共享資源,此時(shí)無(wú)法獲得鎖,只能自旋,產(chǎn)生死鎖。

如何避免死鎖

如果中斷處理函數(shù)中也要獲得自旋鎖,那么驅(qū)動(dòng)程序需要在擁有自旋鎖時(shí)禁止中斷;

自旋鎖必須在可能的最短時(shí)間內(nèi)擁有;

避免某個(gè)獲得鎖的函數(shù)調(diào)用其他同樣試圖獲取這個(gè)鎖的函數(shù),否則代碼就會(huì)死鎖;不論是信號(hào)量還是自旋鎖,都不允許鎖擁有者第二次獲得這個(gè)鎖,如果試圖這么做,系統(tǒng)將掛起;

鎖的順序規(guī)則 按同樣的順序獲得鎖; 如果必須獲得一個(gè)局部鎖和一個(gè)屬于內(nèi)核更中心位置的鎖,則應(yīng)該首先獲取自己的局部鎖 ; 如果我們擁有信號(hào)量和自旋鎖的組合,則必須首先獲得信號(hào)量;在擁有自旋鎖時(shí)調(diào)用down(可導(dǎo)致休眠)是個(gè)嚴(yán)重的錯(cuò)誤的。

死鎖舉例

因?yàn)樽孕i持有時(shí)間非常短,沒(méi)有直觀的現(xiàn)象,下面舉一個(gè)會(huì)導(dǎo)致死鎖的實(shí)例。

運(yùn)行條件

虛擬機(jī):vmware

OS :Ubuntu 14

配置 :將虛擬機(jī)的處理個(gè)數(shù)設(shè)置為1,否則不會(huì)死鎖

原理

針對(duì)單CPU,擁有自旋鎖的任務(wù)不應(yīng)該調(diào)度會(huì)引起休眠的函數(shù),否則會(huì)導(dǎo)致死鎖。

步驟:

進(jìn)程A在open()字符設(shè)備后,對(duì)應(yīng)的內(nèi)核函數(shù)會(huì)申請(qǐng)自旋鎖,此時(shí)自旋鎖空閑,申請(qǐng)到自旋鎖,進(jìn)程A隨即進(jìn)入執(zhí)行sleep()函數(shù)進(jìn)入休眠;

在進(jìn)程A 處于sleep期間,自旋鎖一直屬于進(jìn)程A所有;

運(yùn)行進(jìn)程B,進(jìn)程B執(zhí)行open函數(shù),對(duì)應(yīng)的內(nèi)核函數(shù)也會(huì)申請(qǐng)自旋鎖,此時(shí)自旋鎖歸進(jìn)程A所有,所以進(jìn)程B進(jìn)入自旋狀態(tài);

因?yàn)榇藭r(shí)搶占已經(jīng)關(guān)閉,系統(tǒng)死鎖。

驅(qū)動(dòng)代碼如下:

#include 《linux/init.h》#include 《linux/module.h》#include 《linux/kdev_t.h》#include 《linux/fs.h》#include 《linux/cdev.h》#include 《linux/device.h》#include 《linux/spinlock.h》static int major = 250;static int minor = 0;static dev_t devno;static struct cdev cdev;static struct class *cls;static struct device *test_device;static spinlock_t lock;static int flage = 1;#define DEAD 1static int hello_open (struct inode *inode, struct file *filep){ spin_lock(&lock); if(flage !=1) { spin_unlock(&lock); return -EBUSY; } flage =0; #if DEAD #elif spin_unlock(&lock); #endif return 0;}static int hello_release (struct inode *inode, struct file *filep){ flage = 1; #if DEAD spin_unlock(&lock); #endif return 0;}static struct file_operations hello_ops ={ .open = hello_open, .release = hello_release,};static int hello_init(void){ int result; int error; printk(“hello_init \n”); result = register_chrdev( major, “hello”, &hello_ops); if(result 《 0) { printk(“register_chrdev fail \n”); return result; } devno = MKDEV(major,minor); cls = class_create(THIS_MODULE,“helloclass”); if(IS_ERR(cls)) { unregister_chrdev(major,“hello”); return result; } test_device = device_create(cls,NULL,devno,NULL,“test”); if(IS_ERR(test_device )) { class_destroy(cls); unregister_chrdev(major,“hello”); return result; } spin_lock_init(&lock); return 0;}static void hello_exit(void){ printk(“hello_exit \n”); device_destroy(cls,devno); class_destroy(cls); unregister_chrdev(major,“hello”); return;}module_init(hello_init);module_exit(hello_exit);MODULE_LICENSE(“GPL”);

測(cè)試程序如下:

#include 《stdio.h》#include 《sys/types.h》#include 《sys/stat.h》#include 《fcntl.h》main(){ int fd; fd = open(“/dev/test”,O_RDWR); if(fd《0) { perror(“open fail \n”); return; } sleep(20); close(fd); printf(“open ok \n ”);}

測(cè)試步驟:

編譯加載內(nèi)核

makeinsmod hello.ko

運(yùn)行進(jìn)程A

gcc test.c -o a./a

打開(kāi)一個(gè)新的終端,運(yùn)行進(jìn)程B

gcc test.c -o b./b

注意,一定要在進(jìn)程A沒(méi)有退出的時(shí)候運(yùn)行進(jìn)程B。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(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)投訴
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11758

    瀏覽量

    219009
  • 鎖存
    +關(guān)注

    關(guān)注

    0

    文章

    25

    瀏覽量

    21088
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Everspin EMD4E001G-1Gb自旋轉(zhuǎn)移扭矩MRAM內(nèi)存芯片

    作為自旋轉(zhuǎn)移扭矩MRAM技術(shù)的先行者,Everspin推出的EMD4E001G芯片將MRAM容量提升至1Gb密度,為企業(yè)級(jí)SSD、計(jì)算存儲(chǔ)及網(wǎng)絡(luò)加速器提供了全新的數(shù)據(jù)緩沖區(qū)選擇。
    的頭像 發(fā)表于 03-04 15:55 ?74次閱讀
    Everspin EMD4E001G-1Gb<b class='flag-5'>自旋</b>轉(zhuǎn)移扭矩MRAM內(nèi)存芯片

    面試必看:一文讀懂樂(lè)觀自旋等待:判斷條件、原理與應(yīng)用(含音頻)

    在計(jì)算機(jī)世界里,“等待” 是一個(gè)高頻場(chǎng)景 —— 就像我們?cè)诔信抨?duì)結(jié)賬,CPU 也常常需要等待資源(比如、數(shù)據(jù))釋放。而 “樂(lè)觀自旋等待”,就是 CPU 在等待時(shí)的一種 “聰明策略”。它不盲目
    的頭像 發(fā)表于 02-09 16:59 ?928次閱讀
    面試必看:一文讀懂樂(lè)觀<b class='flag-5'>自旋</b>等待:判斷條件、原理與應(yīng)用(含音頻)

    面試必看!排隊(duì)自旋32位變量的域劃分與核心作用

    在操作系統(tǒng)面試中,并發(fā)同步機(jī)制一直是高頻考點(diǎn),而排隊(duì)自旋作為解決傳統(tǒng)自旋“饑餓” 問(wèn)題的關(guān)鍵技術(shù),其 32 位變量的域劃分更是面試官青睞的 “細(xì)節(jié)題”。不少同學(xué)能說(shuō)出排隊(duì)
    的頭像 發(fā)表于 02-09 16:54 ?806次閱讀
    面試必看!排隊(duì)<b class='flag-5'>自旋</b><b class='flag-5'>鎖</b>32位變量的域劃分與核心作用

    面試必看:排隊(duì)自旋之MCS的實(shí)現(xiàn)原理與關(guān)鍵考點(diǎn)

    在并發(fā)編程面試中,“” 是繞不開(kāi)的核心話題,而自旋作為輕量級(jí)的代表,其優(yōu)化方案更是高頻考點(diǎn)。
    的頭像 發(fā)表于 02-09 16:51 ?746次閱讀
    面試必看:排隊(duì)<b class='flag-5'>自旋</b><b class='flag-5'>鎖</b>之MCS<b class='flag-5'>鎖</b>的實(shí)現(xiàn)原理與關(guān)鍵考點(diǎn)

    中國(guó)科大在合肥、杭州架起全球首個(gè)核自旋量子傳感網(wǎng)

    據(jù)中國(guó)科學(xué)技術(shù)大學(xué)最新消息,該校自旋磁共振實(shí)驗(yàn)室彭新華教授與江敏教授團(tuán)隊(duì)于1月29日凌晨宣布,其在《自然》(Nature)雜志發(fā)表了一項(xiàng)突破性研究成果——通過(guò)革新核自旋量子精密測(cè)量技術(shù),團(tuán)隊(duì)成功構(gòu)建
    的頭像 發(fā)表于 01-30 16:31 ?559次閱讀

    【「Linux 設(shè)備驅(qū)動(dòng)開(kāi)發(fā)(第 2 版)」閱讀體驗(yàn)】Linux內(nèi)核開(kāi)發(fā)基礎(chǔ)

    CPU上的調(diào)度程序來(lái)工作,自旋保護(hù)的資源,在同一時(shí)間只能由一個(gè)CPU使用/訪問(wèn),這使得自旋適用于保證對(duì)稱(chēng)多處理的安全性,也適用于執(zhí)行原子任務(wù) 在內(nèi)核源碼中,使用DEFINE_
    發(fā)表于 01-12 22:45

    【「Linux 設(shè)備驅(qū)動(dòng)開(kāi)發(fā)(第 2 版)」閱讀體驗(yàn)】+讀內(nèi)核處理的核心輔助函數(shù)

    一個(gè)是“”;另一個(gè)是“條件變量”。內(nèi)核中最常見(jiàn)的自旋和互斥,操作系統(tǒng)內(nèi)核通常使用硬件提供的原子操作來(lái)實(shí)現(xiàn)
    發(fā)表于 01-10 22:08

    Linux-RT特點(diǎn)及簡(jiǎn)單應(yīng)用

    Scheduling),允許內(nèi)核中斷正在執(zhí)行的任務(wù)以執(zhí)行更高優(yōu)先級(jí)的任務(wù)。這可以降低任務(wù)響應(yīng)時(shí)間,提高實(shí)時(shí)性能。 內(nèi)核優(yōu)化:Linux-RT對(duì)內(nèi)核中的機(jī)制進(jìn)行了優(yōu)化,減少了
    發(fā)表于 12-05 07:37

    我國(guó)科學(xué)家實(shí)現(xiàn)糾纏增強(qiáng)納米尺度單自旋量子傳感

    在微觀世界中,電子的“自旋”是其基本屬性之一,如同一個(gè)個(gè)微小的磁針。材料的許多宏觀特性,如磁鐵的磁性或超導(dǎo)體的零電阻,都源于這些微觀“磁針”的排列與相互作用。 研究人員介紹,探測(cè)單個(gè)自旋,對(duì)物質(zhì)世界
    的頭像 發(fā)表于 12-03 18:22 ?2006次閱讀
    我國(guó)科學(xué)家實(shí)現(xiàn)糾纏增強(qiáng)納米尺度單<b class='flag-5'>自旋</b>量子傳感

    中國(guó)科學(xué)技術(shù)大學(xué):實(shí)現(xiàn)糾纏增強(qiáng)納米尺度單自旋量子傳感

    中國(guó)科學(xué)技術(shù)大學(xué)與浙江大學(xué)合作,在納米尺度量子精密測(cè)量領(lǐng)域取得進(jìn)展,首次實(shí)現(xiàn)了噪聲環(huán)境下糾纏增強(qiáng)的納米尺度單自旋探測(cè)。 01 測(cè)量最基礎(chǔ)的磁性單元 探測(cè)單個(gè)自旋,測(cè)量物質(zhì)世界最基礎(chǔ)的磁性單元,能夠
    的頭像 發(fā)表于 12-01 18:42 ?1857次閱讀
    中國(guó)科學(xué)技術(shù)大學(xué):實(shí)現(xiàn)糾纏增強(qiáng)納米尺度單<b class='flag-5'>自旋</b>量子傳感

    致真精密儀器自旋測(cè)試多功能克爾顯微鏡進(jìn)行磁疇結(jié)構(gòu)表征分析

    近日,以中國(guó)科學(xué)院蘇州納米技術(shù)與納米仿生研究所、意大利墨西拿大學(xué)等機(jī)構(gòu)為核心的國(guó)際化科研團(tuán)隊(duì),在拓?fù)?b class='flag-5'>自旋電子器件與斯格明子應(yīng)用研究中取得重要進(jìn)展。該研究以“Topological
    的頭像 發(fā)表于 11-05 14:38 ?707次閱讀
    致真精密儀器<b class='flag-5'>自旋</b>測(cè)試多功能克爾顯微鏡進(jìn)行磁疇結(jié)構(gòu)表征分析

    致真精密儀器出席第七屆自旋存儲(chǔ)與計(jì)算學(xué)術(shù)研討會(huì)

    10月17日,由超低功耗自旋存儲(chǔ)與計(jì)算111引智基地、自旋芯片與技術(shù)全國(guó)重點(diǎn)實(shí)驗(yàn)室主辦,北京航空航天大學(xué)集成電路科學(xué)與工程學(xué)院、杭州北航國(guó)際創(chuàng)新研究院(學(xué)院)承辦,致真精密儀器有限公司等單位協(xié)辦的第
    的頭像 發(fā)表于 10-23 11:13 ?852次閱讀

    五大認(rèn)證加冕!德施曼以“首創(chuàng)AI智能”重構(gòu)智能競(jìng)爭(zhēng)格局

    近日,智能領(lǐng)軍品牌德施曼獲得尚普咨詢(xún)及中研世紀(jì)兩大權(quán)威機(jī)構(gòu)頒發(fā)的中國(guó)“首創(chuàng)AI智能”、“AI智能領(lǐng)導(dǎo)者”、“AI智能全國(guó)銷(xiāo)量第一”、“AI智能鎖好評(píng)率第一”、“AI智能
    的頭像 發(fā)表于 09-20 10:41 ?1157次閱讀

    什么是電磁控制板?24路控板的使用步驟概述

    電磁控制板是一種專(zhuān)用于控制電磁工作狀態(tài)的電子裝置,它可以接收指令并對(duì)電磁進(jìn)行通斷電操作,從而實(shí)現(xiàn)對(duì)相關(guān)設(shè)備的鎖定和解鎖控制。電磁本身依靠電流產(chǎn)生磁場(chǎng)作用力來(lái)吸附或釋放
    的頭像 發(fā)表于 07-14 16:26 ?779次閱讀
    什么是電磁<b class='flag-5'>鎖</b>控制板?24路<b class='flag-5'>鎖</b>控板的使用步驟概述

    TDK成功研發(fā)出世界首臺(tái)自旋光電探測(cè)器

    TDK宣布其已成功研發(fā)出世界首臺(tái)“自旋光電探測(cè)器”,一款集成光、電子和磁性元件的光自旋電子轉(zhuǎn)換元件一通過(guò)利用波長(zhǎng)為800納米的光,將響應(yīng)速度提高至20皮秒(20×10-12秒),比傳統(tǒng)基于半導(dǎo)體
    的頭像 發(fā)表于 04-24 16:18 ?969次閱讀
    TDK成功研發(fā)出世界首臺(tái)<b class='flag-5'>自旋</b>光電探測(cè)器