作業系統(Linux)多執行緒 訊號量實現同步

2021-07-23 22:49:46 字數 2885 閱讀 1254

程序通訊ipc(inter process communication),實現程序通訊的方法有很多,管道,訊息佇列,共享記憶體,訊號量和socket。

題目為:假定有乙個生產者和乙個消費者,生產者每次生產一件產品,並且把生產的產品存入共享緩衝區以供消費者取走使用。

消費者每次從緩衝區內取出的一件產品去消費。禁止生產者將產品放入已滿的緩衝器內,禁止消費者從緩衝器內取產品。假定緩衝

區可同時存放10件產品,用pv操作實現消費者與生產者的同步問題。

這是一道很常見的同步問題,我用訊號量來實現。

訊號量是用於多個程序(執行緒)對共享資料的訪問的計數器:

1.當訊號量的值為正時,則程序(執行緒)可以使用該資源。在這種情況下,程序(執行緒)會將訊號量減1,表示它使用了乙個資源單位。

2.當訊號量為0,則程序進入休眠狀態,直到訊號量大於0。程序被喚醒後,它返回步驟1。

常用訊號量形式被稱作二元訊號量。它控制單個資源,其初始值為1。但是訊號量可以是任意乙個正值,該值表示有多個共享著資源單位可共享應用。

unix提供了兩種訊號量,xsi和posix訊號量。

在 本例子中用posix訊號量實現。

訊號量分為命名訊號量和未命名訊號量。

在使用posix呼叫sem_init函式來建立乙個未命名的訊號量和sem_destory丟棄使用完的訊號量。

sem_init函式:

#include int sem_init(sem_t *sem, int pshared, unsigned int value);

pshared表明是否在多個程序中使用訊號量。如果不為0時此訊號量在程序間共享,否則只能為當前程序的所有執行緒共享。

value表示訊號量的初始值。

sem_t:訊號量的資料結構,本質是有個長整型的數。

sem_destroy函式:

#include int sem_destroy(sem_t *sem);
對於未命名訊號的使用已經完成時,可以呼叫sem_destroy函式丟棄它。

呼叫sem_destroy後,不能再使用任何帶有sem的訊號函式,除非通過呼叫sem_init重新初始化它。

sem_wait函式:

#include int sem_wait(sem_t *sem)
使用sem_wait函式時,實現訊號量減1的操作,如果訊號量計數是0就會發生阻塞。直到成功使訊號量減1或者被訊號中斷才返回。

sem_post函式:

#include int  sem_post(sem_t *sem);
實現訊號量增1的操作,在呼叫sem_post時,如果在呼叫sem_wait中發生程序阻塞。那麼程序會被喚醒並且被sem_post增加1的訊號量計數會再次被sem_wait減1。

首先建立乙個訊號量sem_mutex表示對緩衝區的操作,用sem_init(&sem_mutex,0,1)初始化。0表示使用得是執行緒,1表示只有乙個共享資源。

每次對緩衝區進行操作時,就需要呼叫sem_wait(&sem_mutex)相當於p操作,表示正在操作緩衝區,由於初始值為1,所以其他執行緒想對其操作時,必須等待此操作呼叫sem_post相對於v操作,表示對其操作結束,另乙個執行緒可以進入對其操作。這樣就可以實現資料的同步,避免出現與"時間相關的錯誤"。

由於生產者和消費者分別用乙個執行緒執行操作,由於執行緒時可以共享資料的。

定義乙個結構體表示緩衝佇列的資源,佇列裡面可以放10個字元,num表示已經放入緩衝區的數量。

當生產者執行時num++,消費者執行時num--。

rear,front便於存入和列印出字元

訊號量s1和s2分別表示對緩衝區空位置的操作和表示緩衝區已經放入的產品的操作

s1和s2的初始值分別為10和1

當s1小於10時表示生產者繼續向緩衝區的空位置放入產品的操作

當s2大於0時表示消費者可以從緩衝區裡面繼續取產品操作

#include #include #include #include #include sem_t sem_mutex;//表示對緩衝區的操作

sem_t s1;//訊號量s1表示緩衝區區還可以放入的產品

sem_t s2;//訊號量s2表示緩衝區已經放的產品

#define buff_size 10

struct p_queue;

void* producer(void *arg)

sem_post(&sem_mutex);

sleep(rand()%2);

} return null;

}void* consumer(void *arg)

sem_post(&sem_mutex);

sleep(rand()%2);}}

int main()

效果:

由於執行緒排程是由作業系統控制的,所以並不是執行一次生產者,就接著執行一次消費者。

注意執行的時候應該加 -lpthread,不然會找不到sem_wait,sem_post,sem_init等函式

訊號量分為命名訊號量和未命名訊號量。

在使用posix呼叫sem_init函式來建立乙個未命名的訊號量和sem_destory丟棄使用完的訊號量。

首先建立乙個訊號量sem_mutex表示對緩衝區的操作,用sem_init(&sem_mutex,0,1)初始化。0表示使用得是執行緒,1表示只有乙個共享資源。

作業系統訊號量

本文將針對較為簡單的生產者消費者問題,給出利用訊號量解決問題的方法。生產者 能產生並投放資源的程序 消費者 單純使用 消耗 資源的程序 問題表述 一組 生產者程序和一 組消費者程序 設每組有多個程序 通過緩衝區發生聯絡。生產者程序將生產的產品 資料 訊息等統稱為產品 送入緩衝區,消費者程序從中取出產...

作業系統 訊號量

代表了一類物理資源,是相應的物理資源的抽象,通常為整型或結構體型,除了初始化之外,其他情況下只能使用p v進行操作 執行一次p s 則s.value減一,若執行p s 之後s.value 0,則表示該類資源可用,否則不可用 執行一次v s 則s.value加一,若執行v操作以後,s.value的值仍...

多執行緒 訊號量

訊號量 semaphore類 建立帶指定許可數的訊號量 semaphore semaphore new semaphore 1 建立乙個許可的訊號量 訊號量用來限制訪問共享數資源的執行緒數。在訪問資源之前,執行緒必須從訊號量獲取許可,在訪問完資源後釋放訊號量。任務通過呼叫訊號量的acquire 方法...