Concurrency and Race Condition

來源:互聯網
上載者:User

產生競爭的原因:

   對資源的共用訪問,包括硬體資源(裝置)和軟體資源(記憶體空間)

 

原則:

   盡量減少共用資源的使用,如全域變數等

 

解決的方法:

   通過建立critical section是操作成為原子操作,使同一時間內,只有一個線程操作該段代碼。

   kernel對不同的情況提供了不同的方法,注意的是,有的方法可以 Go to sleep
的,有的不行!

   有的方法會導致執行的線程go to sleep,而有的方法不會。

   有的代碼是允許sleep的,那就可以使用go to sleep的方法。

   但有的代碼是不允許sleep的,那就絕對不能go to sleep的方法。

   spinlock就是可以用在不允許sleep的代碼中的。

 

Semaphore

 

標頭檔<asm/semaphore.h>.

struct semaphore;

 

初始化 訊號量

void sema_init(struct semaphore *sem, int val);

where val is the initial value to assign to a semaphore.

 

直接聲明 互斥量

Thus, a mutex can be declared and initialized with one of the following:
DECLARE_MUTEX(name);
DECLARE_MUTEX_LOCKED(name);

 

運行時 初始化

void init_MUTEX(struct semaphore *sem);
void init_MUTEX_LOCKED(struct semaphore *sem);

 

擷取訊號量

void down(struct semaphore *sem);
int down_interruptible(struct semaphore *sem);
int down_trylock(struct semaphore *sem);

用down_interruptible比較多,這樣使用者可以中斷這個函數的執行。

所以一定要對這個函數做傳回值的判斷,如果返回非零,則表示並沒有得到訊號量。

 

返還訊號量

void up(struct semaphore *sem);

 

例子:

struct scull_dev {
    struct scull_qset *data; /* Pointer to first quantum set */
    int quantum; /* the current quantum size */
    int qset; /* the current array size */
    unsigned long size; /* amount of data stored here */
    unsigned int access_key; /* used by sculluid and scullpriv */
    struct semaphore sem; /* mutual exclusion semaphore */
    struct cdev cdev; /* Char device structure */
};

 

for (i = 0; i < scull_nr_devs; i++) {
    scull_devices[i].quantum = scull_quantum;
    scull_devices[i].qset = scull_qset;
    init_MUTEX(&scull_devices[i].sem);
    scull_setup_cdev(&scull_devices[i], i);
}

一定要在scull_setpu_cdev之前初始化訊號量,否則會出現錯誤。

 

讀寫訊號量

這種訊號量使用於 有多個讀進程,少量寫進程。 可以同時有多個讀進程一起運行。

 

標頭檔 <linux/rwsem.h>

struct rw_semaphore

 

讀操作的訊號量擷取和釋放

void down_read(struct rw_semaphore *sem);
int down_read_trylock(struct rw_semaphore *sem);
void up_read(struct rw_semaphore *sem);

 

寫操作的訊號量擷取和釋放

void down_write(struct rw_semaphore *sem);
int down_write_trylock(struct rw_semaphore *sem);
void up_write(struct rw_semaphore *sem);
void downgrade_write(struct rw_semaphore *sem);

 

 

Completions

這種結構專門用於等待其他任務的完成的。

雖然用訊號量也可以達到這個作用,但訊號量的效率要低。

struct semaphore sem;
init_MUTEX_LOCKED(&sem);
start_external_task(&sem);
down(&sem);

 

標頭檔 <linux/completion.h>

struct completion;

 

靜態聲明:
DECLARE_COMPLETION(my_completion);

 

動態定義:

struct completion my_completion;
/* ... */
init_completion(&my_completion);

 

 

等待任務完成:

void wait_for_completion(struct completion *c);

 

通知任務完成:

void complete(struct completion *c);
void complete_all(struct completion *c);

 

Spinlock

spinlock是比較特殊的一種鎖,它是可以運行在不能sleep的地方的,比如 ISR中。

進入spinlock後,有幾點要注意

1. 不能被搶佔,這點是自動的,得到spinlock後會自動disable當前處理器的搶佔。

2. 不能sleep, 所以需要非常注意得到spinlock後調用的函數。

3. disable 中斷。

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.