1. 程式人生 > >linux條件變數

linux條件變數

條件變數:

條件變數本身不是鎖!但它也可以造成執行緒阻塞。通常與互斥鎖配合使用。給多執行緒提供一個會合的場所。

主要應用函式:

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);

參2: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);

函式作用:

1. 阻塞等待條件變數cond(參1)滿足

2. 釋放已掌握的互斥鎖(解鎖互斥量)相當於pthread_mutex_unlock(&mutex);

 1.2.兩步為一個原子操作。

3. 當被喚醒,pthread_cond_wait函式返回時,解除阻塞並重新申請獲取互斥鎖pthread_mutex_lock(&mutex);

pthread_cond_timedwait函式

限時等待一個條件變數

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

參3: 參看man sem_timedwait函式,檢視struct timespec結構體。

struct timespec {

time_t tv_sec; /* seconds */ 秒

long   tv_nsec; /* nanosecondes*/ 納秒

}

形參abstime:絕對時間。

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

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); 傳參 參APUE.11.6執行緒同步條件變數小節

在講解setitimer函式時我們還提到另外一種時間型別:

        struct timeval {

             time_t      tv_sec;  /* seconds */ 秒

             suseconds_t tv_usec; /* microseconds */ 微秒

        };

pthread_cond_signal函式

喚醒至少一個阻塞在條件變數上的執行緒

int pthread_cond_signal(pthread_cond_t *cond);

pthread_cond_broadcast函式

喚醒全部阻塞在條件變數上的執行緒

    int pthread_cond_broadcast(pthread_cond_t *cond);

生產者消費者條件變數模型

執行緒同步典型的案例即為生產者消費者模型,而藉助條件變數來實現這一模型,是比較常見的一種方法。假定有兩個執行緒,一個模擬生產者行為,一個模擬消費者行為。兩個執行緒同時操作一個共享資源(一般稱之為匯聚),生產向其中新增產品,消費者從中消費掉產品。

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

【conditionVar_product_consumer.c】

/*藉助條件變數模擬 生產者-消費者 問題*/
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>

/*連結串列作為公享資料,需被互斥量保護*/
struct msg {
    struct msg *next;
    int num;
};

struct msg *head;
struct msg *mp;

/* 靜態初始化 一個條件變數 和 一個互斥量*/
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void *consumer(void *p)
{
    for (;;) {
        pthread_mutex_lock(&lock);
        while (head == NULL) {           //頭指標為空,說明沒有節點    可以為if嗎
            pthread_cond_wait(&has_product, &lock);
        }
        mp = head;      
        head = mp->next;    //模擬消費掉一個產品
        pthread_mutex_unlock(&lock);

        printf("-Consume ---%d\n", mp->num);
        free(mp);
        mp = NULL;
        sleep(rand() % 5);
    }
}

void *producer(void *p)
{
    for (;;) {
        mp = malloc(sizeof(struct msg));
        mp->num = rand() % 1000 + 1;        //模擬生產一個產品
        printf("-Produce ---%d\n", mp->num);

        pthread_mutex_lock(&lock);
        mp->next = head;
        head = mp;
        pthread_mutex_unlock(&lock);

        pthread_cond_signal(&has_product);  //將等待在該條件變數上的一個執行緒喚醒
        sleep(rand() % 5);
    }
}

int main(int argc, char *argv[])
{
    pthread_t pid, cid;
    srand(time(NULL));

    pthread_create(&pid, NULL, producer, NULL);
    pthread_create(&cid, NULL, consumer, NULL);

    pthread_join(pid, NULL);
    pthread_join(cid, NULL);

    return 0;
}


條件變數的優點:

相較於mutex而言,條件變數可以減少競爭。

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


相關推薦

linux 條件變數 互斥鎖的實現

這是一個經典的猴子吃桃子的問題的實現(生產-消費者問題) 有一棵桃樹和一隻猴子,開始的時候桃樹上沒有桃子,然後開始一個一個的長,每長一個猴子就吃一個,猴子吃了之後再長一個,又被猴子吃掉,猴子需要吃7個桃子,才能吃飽。編寫程式模擬這個猴子吃桃子的過程。

linux條件變數

條件變數: 條件變數本身不是鎖!但它也可以造成執行緒阻塞。通常與互斥鎖配合使用。給多執行緒提供一個會合的場所。 主要應用函式: pthread_cond_init函式 pthread_cond_des

linux條件變數使用和與訊號量的區別

近來在專案中用到條件變數和訊號量做同步時,這一塊一直都有了解,但也一直沒有總結,這次總結一下,給大家提供點參考,也給自己留點紀念。 首先,關於訊號量和條件變數的概念可以自行檢視APUE,我這直接把APUE中的程式碼拿過來對比; 條件變數的使用: #include <pthread.h> str

Linux多執行緒程式設計---執行緒間同步(互斥鎖、條件變數、訊號量和讀寫鎖)

本篇博文轉自http://zhangxiaoya.github.io/2015/05/15/multi-thread-of-c-program-language-on-linux/ Linux下提供了多種方式來處理執行緒同步,最常用的是互斥鎖、條件變數、訊號量和讀寫鎖。  下面是思維導

linux下用互斥鎖和條件變數來實現讀寫鎖

以下內容來源自UNP卷二的第八章 讀寫鎖的概念( the conception of read-write lock ) (1)只要沒有執行緒持有某個給定的讀寫鎖用於寫,那麼任意數目的執行緒可以持有該執行緒用於讀 (2)僅當沒有執行緒持有某個給定的讀寫鎖用於讀或用於寫,才能分配該

linux執行緒】執行緒安全之條件變數

條件變數用法: 條件變數一般和互斥量配合,保護執行緒安全或者完成同步資料的功能。 #include <pthread.h> #define INFINITE 0xFFFFFFFF #ifndef ETIMEDOUT #define ETIMEDOUT 10060 #endif

Linux 執行緒同步---條件變數

        pthread_cond_signal 使在條件變數上等待的執行緒中的一個執行緒重新開始。如果沒有等待的執行緒,則什麼也不做。如果有多個執行緒在等待該條件,只有一個能重啟動,但不能指定哪一個。    

Linux執行緒同步之條件變數pthread_cond_t

Linux執行緒同步之條件變數pthread_cond_t  一直以來都天真的認為執行緒間同步的方法只有訊號量,互斥量,郵箱,訊息佇列,知道最近開始研究一些Linux方面的程式碼才發現自己是多麼的很傻很天真。在Linux中還存在這一種叫做條件變數的東西。必須承認我在理解這個概念上花了很

Linux作業系統下的多執行緒程式設計詳細解析----條件變數pthread_cond_t

在多執行緒程式設計下,常常出現A執行緒要等待B執行緒條件完成後再繼續進行,這裡等待方式有兩種: 1.使用鎖+輪詢        使用這種方法可以很簡單的實現,但是會有一定的效能消耗,其還有一個點要好好把握,就是一次輪詢沒有結果後相隔多久進行下一次的輪詢,間隔時間太短,消耗

Linux 學習筆記—執行緒同步之互斥量與條件變數

執行緒同步(同步的意思是協同步調) 執行緒同步機制包括互斥,讀寫鎖以及條件變數等 3.2.1 互斥量(互斥鎖) **互斥量本質是一把鎖,在訪問公共資源前對互斥量設定(加鎖),確保同一時間只有一個執行緒訪問資料,在訪問完成後再釋放(解鎖)互斥量。**在互斥量加鎖之

Linux下互斥量與條件變數詳細解析

引用下POSIX的RATIONALE: Condition Wait Semantics It is important to note that when pthread_cond_wait() andpthread_cond_timedwait() return without error, the as

Linux下面的執行緒鎖,條件變數以及訊號量的使用

一) 執行緒鎖1) 只能用於"鎖"住臨界程式碼區域2) 一個執行緒加的鎖必須由該執行緒解鎖.鎖幾乎是我們學習同步時最開始接觸到的一個策略,也是最簡單, 最直白的策略.二) 條件變數,與鎖不同, 條件變數用於等待某個條件被觸發1) 大體使用的偽碼:// 執行緒一程式碼pthread_mutex_lock

Linux多執行緒實踐(8) --Posix條件變數解決生產者消費者問題

Posix條件變數int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); int pthread_cond_destroy(pthread_cond_t *cond); int

linux同步機制條件變數

目錄   1、條件變數 2、條件變數API 2.1 pthread_cond_init 2.2 pthread_cond_wait 2.3 pthread_cond_timedwait 2.4 pthread_cond_signal

Linux 多執行緒同步問題 條件變數

互斥鎖:用來上鎖。 條件變數:用來等待,當條件變數用來自動阻塞一個執行緒,直到某特殊情況發生為止。通常條件變數和互斥鎖同時使用。 函式介紹: 1. 名稱: pthread_cond_init 目標: 條件變數初始化 標頭檔案: #include &

Linux C 多執行緒程式設計】互斥鎖與條件變數

一、互斥鎖互斥量從本質上說就是一把鎖, 提供對共享資源的保護訪問。  1. 初始化:  在Linux下, 執行緒的互斥量資料型別是pthread_mutex_t. 在使用前, 要對它進行初始化:  對於靜態分配的互斥量, 可以把它設定為PTHREAD_MUTEX_INITIA

linux程式設計---執行緒---條件變數

條件變數通訊機制 基本原理 初始化條件變數 int pthread_cond_init(pthread_cond_t *restrict cond,               const pthread_condattr_t *restrict attr);      

Linux執行緒---執行緒同步互斥:條件變數

使用互斥鎖可實現執行緒間資料的共享和通訊,互斥鎖的一個明顯的缺點是它只有兩種狀態:鎖定和非鎖定。二條件變數通過允許執行緒阻塞和等待另一個執行緒傳送訊號的方法彌補了互斥鎖的不足,它常和互斥鎖一起使用。 使用時,條件變數被用來阻塞一個執行緒,當條件不滿足時,執行緒

四十一、Linux 執行緒——執行緒同步之條件變數

41.1 概念 41.1.1 條件變數的介紹 互斥鎖的缺點是它只有兩種狀態:鎖定和非鎖定 條件變數通過允許執行緒阻塞和等待另一個執行緒傳送訊號的方法彌補了互斥鎖的不足 條件變數內部是一個等待佇列,放置等待的執行緒,執行緒在條件變數上等待和通知,互斥鎖用來保護等待佇列(對等待佇列上鎖),條件變

Linux多執行緒學習(2)--執行緒的同步與互斥及死鎖問題(互斥量和條件變數)

Linux多執行緒學習總結 一.互斥量 1.名詞理解 2.什麼是互斥量(mutex) 3.互斥量的介面 3.1 初始化訊號量 3.2 銷燬訊號量 3.3 互斥量加鎖和解鎖