Linux內(nèi)核--并發(fā)

為什么會產(chǎn)生并發(fā)

1、多個用戶同時登陸的時候,他們有可能在任何時刻以任意的組合調(diào)用內(nèi)核代碼。

2、smp系統(tǒng)可能同時在不同的處理器上執(zhí)行你的代碼。

3、內(nèi)核代碼是搶占式的,你的程序有可能隨時被剝奪掉處理器。

4、設(shè)備中斷可能導(dǎo)致并發(fā)的異步事件。

5、內(nèi)核也提供了各種延遲代碼執(zhí)行機(jī)制,如工作隊列等,任務(wù)隊列和定時器,它可以使你在與當(dāng)前進(jìn)程無關(guān)的方法中運行代碼

并發(fā)帶來的影響

并發(fā)產(chǎn)生了競爭條件,比如兩個進(jìn)程同時訪問相同的硬件資源

應(yīng)對的基本原則是:盡量避免共享數(shù)據(jù)

如果無法避免那就一定要注意共享的數(shù)據(jù)。

Linux 的 信號量

#include <linux/semaphore.h>

/*
* Copyright (c) 2008 Intel Corporation
* Author: Matthew Wilcox <willy@linux.intel.com>
*
* Distributed under the terms of the GNU GPL, version 2
*
* Please see kernel/semaphore.c for documentation of these
functions
*/
#ifndef __LINUX_SEMAPHORE_H
#define __LINUX_SEMAPHORE_H
#include <linux/list.h>
#include <linux/spinlock.h>
/* Please don't access any members of this structure directly */
struct semaphore {
    raw_spinlock_t lock;
    unsigned int count;
    struct list_head wait_list;
};
#define __SEMAPHORE_INITIALIZER(name , n)
{
    .lock = __RAW_SPIN_LOCK_UNLOCKED((name).lock),
    .count = n,
    .wait_list = LIST_HEAD_INIT((name).wait_list),
} #
define DEFINE_SEMAPHORE(name) struct semaphore name = __SEMAPHORE_INITIALIZER(name , 1)
static inline void sema_init(struct semaphore *sem, int val)
{
    static struct lock_class_key __key;
    *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);
    lockdep_init_map(&sem->lock.dep_map , "semaphore ->lock", &__key , 0);
}
extern void down(struct semaphore *sem);
extern int __must_check down_interruptible(struct semaphore *sem);
extern int __must_check down_killable(struct semaphore *sem);
extern int __must_check down_trylock(struct semaphore *sem);
extern int __must_check down_timeout(struct semaphore *sem, long jiffies);
extern void up(struct semaphore *sem);
#endif /* __LINUX_SEMAPHORE_H */

down方法將信號量的值減一然后等到信號量的值大于等于零繼續(xù)執(zhí)行。

down_interruptible跟down類似但是可以被中斷,建議使用這個API,只使用down容易造成該線程永遠(yuǎn)無法退出。

一般的使用方法是:

if (down_interruptible(&sem))
    return -ERESTARTSYS;

讀寫信號量

一種常見的信號量,針對共享文件,允許多個線程同時讀,而讀的時候不允許寫。在同一時間只允許一個線程寫。

#include <linux/rwsem.h>

自旋鎖

自旋鎖最初是為了SMP系統(tǒng)設(shè)計的,實現(xiàn)在多處理器情況下保護(hù)臨界區(qū)。
自旋鎖只有兩種狀態(tài),上鎖,未上鎖,經(jīng)常被用來確保一段代碼的原子性

spinlock API:

void spin_lock(spinlock_t *lock);
void spin_lock_irqsave(spinlock_t *lock , unsigned long flags);
void spin_lock_irq(spinlock_t *lock);
void spin_lock_bh(spinlock_t *lock);

讀寫自旋鎖

linux內(nèi)核提供了讀寫自旋鎖,實際上它與讀寫信號量很相似。

上鎖的要求

1、如果你在自己的代碼里實現(xiàn)了一個設(shè)備鎖,而你也要套用到linux內(nèi)核提供的鎖,請先把自己的鎖鎖上,再把系統(tǒng)的鎖鎖上。

2、如果你使用信號量和自旋鎖,請先down信號量,再使用自旋鎖。

3、確保自旋鎖內(nèi)沒有其他的鎖,以防系統(tǒng)被死鎖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容