中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux如何實現條件變量

發布時間:2021-10-23 15:36:55 來源:億速云 閱讀:273 作者:小新 欄目:系統運維

這篇文章給大家分享的是有關Linux如何實現條件變量的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

條件變量是用來等待線程而不是上鎖的,條件變量通常和互斥鎖一起使用。條件變量之所以要和互斥鎖一起使用,主要是因為互斥鎖的一個明顯的特點就是它只有兩種狀態:鎖定和非鎖定,而條件變量可以通過允許線程阻塞和等待另一個線程發送信號來彌補互斥鎖的不足,所以互斥鎖和條件變量通常一起使用。

當條件滿足的時候,線程通常解鎖并等待該條件發生變化,一旦另一個線程修改了環境變量,就會通知相應的環境變量喚醒一個或者多個被這個條件變量阻塞的線程。這些被喚醒的線程將重新上鎖,并測試條件是否滿足。一般來說條件變量被用于線程間的同步;當條件不滿足的時候,允許其中的一個執行流掛起和等待。

簡而言之,條件變量本身不是鎖,但它也可以造成線程阻塞,通常與互斥鎖配合使用,給多線程提供一個會合的場所。

條件變量的優點:

  • 相較于mutex而言,條件變量可以減少競爭。如果僅僅是mutex,那么,不管共享資源里有沒數據,生產者及所有消費都全一窩蜂的去搶鎖,會造成資源的浪費。

  • 如直接使用mutex,除了生產者、消費者之間要競爭互斥量以外,消費者之間也需要競爭互斥量,但如果匯聚(鏈表)中沒有數據,消費者之間競爭互斥鎖是無意義的。有了條件變量機制以后,只有生產者完成生產,才會引起消費者之間的競爭。提高了程序效率。

主要應用函數:

  • pthread_cond_init函數

  • pthread_cond_destroy函數

  • pthread_cond_wait函數

  • pthread_cond_timedwait函數

  • pthread_cond_signal函數

  • pthread_cond_broadcast函數

以上6 個函數的返回值都是:成功返回0, 失敗直接返回錯誤號。

pthread_cond_t類型:用于定義條件變量,比如:pthread_cond_t cond;

##pthread_cond_init函數

函數原型:

int pthread_cond_init(pthread_cond_t restrict cond, const pthread_condattr_t restrict attr);

函數作用:初始化一個條件變量

參數說明:

  • cond:條件變量,調用時應傳&cond給該函數

  • attr:條件變量屬性,通常傳NULL,表示使用默認屬性

也可以使用靜態初始化的方法,初始化條件變量:

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

##pthread_cond_destroy函數

函數原型:

int pthread_cond_destroy(pthread_cond_t *cond);

函數作用:銷毀一個條件變量

##pthread_cond_wait函數

函數原型:

int pthread_cond_wait(pthread_cond_t restrict cond, pthread_mutex_t restrict mutex);

函數作用:

阻塞等待一個條件變量。具體而言有以下三個作用:

  • 阻塞等待條件變量cond(參1)滿足;

  • 釋放已掌握的互斥鎖mutex(解鎖互斥量)相當于pthread_mutex_unlock(&mutex);

  • 當被喚醒,pthread_cond_wait函數返回時,解除阻塞并重新申請獲取互斥鎖

其中1、2.兩步為一個原子操作。

##pthread_cond_timedwait函數

函數原型:

int pthread_cond_timedwait(pthread_cond_t restrict cond, pthread_mutex_t restrict mutex, const struct timespec *restrict abstime);

函數作用:限時等待一個條件變量

參數說明:

前兩個比較好理解,重點說明第三個參數。

這里有個struct timespec結構體,可以在man sem_timedwait中查看。結構體原型如下:

struct timespec {  time_t tv_sec; / seconds / 秒   long tv_nsec; / nanosecondes/ 納秒  }

struct  timespec定義的形參abstime是個絕對時間。注意,是絕對時間,不是相對時間。什么是絕對時間?2018年10月1日10:10:00,這就是一個絕對時間。什么是相對時間?給洗衣機定時30分鐘洗衣服,就是一個相對時間,也就是說從當時時間開始計算30分鐘,諸如此類。

如:time(NULL)返回的就是絕對時間。而alarm(1)是相對時間,相對當前時間定時1秒鐘。

adstime所相對的時間是相對于1970年1月1日00:00:00,也就是UNIX計時元年。

下面給出一個錯誤用法: struct timespec t = {1, 0}; pthread_cond_timedwait (&cond,  &mutex, &t); 這種用法只能定時到 1970年1月1日 00:00:01秒,想必這個時間大家都還沒出生。

正確用法: time_t cur = time(NULL); 獲取當前時間。 struct timespec t; 定義timespec 結構體變量t  t.tv_sec = cur+1; 定時1秒 pthread_cond_timedwait (&cond, &mutex, &t);  傳參

##pthread_cond_signal函數

函數原型:

int pthread_cond_signal(pthread_cond_t *cond);

函數作用: 喚醒至少一個阻塞在條件變量上的線程

##pthread_cond_broadcast函數

函數原型:

int pthread_cond_broadcast(pthread_cond_t *cond);

函數作用: 喚醒全部阻塞在條件變量上的線程

##生產者消費者條件變量模型

不管是什么語言,只要提到線程同步,一個典型的案例就是生產者消費者模型。在Linux環境下,借助條件變量來實現這一模型,是比較常見的一種方法。

假定有兩個線程,一個模擬生產者行為,一個模擬消費者行為。兩個線程同時操作一個共享資源(一般稱之為匯聚),生產向其中添加產品,消費者從中消費掉產品。

看如下示例,使用條件變量模擬生產者、消費者問題:

#include <stdio.h> #include <stdlib.h>#include <unistd.h>#include <pthread.h>typedef struct msg {    struct msg *next;     int num;}msg_t;msg_t *head = NULL;msg_t *mp = NULL;/* 靜態初始化 一個條件變量 和 一個互斥量*/pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER;void *th_producer(void *arg) {    while (1) {         mp = malloc(sizeof(msg_t));        mp->num = rand() % 1000;        //模擬生產一個產品         printf("--- produce: %d --------\n", mp->num);         pthread_mutex_lock(&mutex);        mp->next = head;         head = mp;        pthread_mutex_unlock(&mutex);        pthread_cond_signal(&has_product);      //喚醒線程去消費產品        sleep(rand() % 5);     }    return NULL; }void *th_consumer(void *arg) {    while (1) {         pthread_mutex_lock(&mutex);        while (head == NULL) {      //如果鏈表里沒有產品,就沒有搶鎖的必要,一直阻塞等待             pthread_cond_wait(&has_product, &mutex);        }        mp = head;        head = mp->next;        //模擬消費掉一個產品         pthread_mutex_unlock(&mutex);        printf("========= consume: %d ======\n", mp->num);         free(mp);        mp = NULL;        sleep(rand() % 5);     }    return NULL; }int main(){    pthread_t pid, cid;    srand(time(NULL));     pthread_create(&pid, NULL, th_producer, NULL);    pthread_create(&cid, NULL, th_consumer, NULL);    pthread_join(pid, NULL);    pthread_join(cid, NULL);    return 0; }

運行結果:

Linux如何實現條件變量

感謝各位的閱讀!關于“Linux如何實現條件變量”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

惠来县| 中山市| 尤溪县| 岳西县| 枞阳县| 洛川县| 玉林市| 绥芬河市| 米林县| 盐亭县| 北川| 绥棱县| 芦山县| 喀什市| 古田县| 萨迦县| 外汇| 沂水县| 南城县| 枣庄市| 灵宝市| 贵定县| 韩城市| 普兰县| 汉源县| 新郑市| 抚州市| 阳原县| 南郑县| 巴东县| 莒南县| 秀山| 景德镇市| 棋牌| 团风县| 于都县| 札达县| 呼和浩特市| 河北省| 克山县| 玉林市|