多線程鎖

1. 背景知識(shí):
多線程中經(jīng)常需要使用到鎖(pthread_mutex_t)來完成多個(gè)線程之間的某些同步操作
? 互斥鎖:為了使不同線程互斥的使用某個(gè)資源
    ○ 鎖的創(chuàng)建:pthread_mutex_init
        § pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
        § int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t * attr);
    ○ 鎖的屬性:
        pthread_mutexattr_init(pthread_mutexattr_t *mattr)
        pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type)
        pthread_mutexattr_gettype(pthread_mutexattr_t *attr , int *type)
        § 普通鎖:PTHREAD_MUTEX_TIMED_NP(當(dāng)一個(gè)線程加鎖以后,其余請(qǐng)求鎖的線程將形成一個(gè)等待隊(duì)列争舞,并在解鎖后按優(yōu)先級(jí)獲得鎖翩迈。這種鎖策略保證了資源分配的公平性)
        § 嵌套鎖:PTHREAD_MUTEX_RECURSIVE_NP(允許同一個(gè)線程對(duì)同一個(gè)鎖成功獲得多次,并通過多次unlock解鎖絮缅。如果是不同線程請(qǐng)求,則在加鎖線程解鎖時(shí)重新競(jìng)爭(zhēng))
        § 檢錯(cuò)鎖:PTHREAD_MUTEX_ERRORCHECK_NP(如果同一個(gè)線程請(qǐng)求同一個(gè)鎖呼股,則返回EDEADLK耕魄,否則與PTHREAD_MUTEX_TIMED_NP類型動(dòng)作相同。這樣就保證當(dāng)不允許多次加鎖時(shí)不會(huì)出現(xiàn)最簡(jiǎn)單情況下的死鎖)
        § 適應(yīng)鎖:PTHREAD_MUTEX_ADAPTIVE_NP(動(dòng)作最簡(jiǎn)單的鎖類型彭谁,僅等待解鎖后重新競(jìng)爭(zhēng))
    ○ 鎖的釋放:pthread_mutex_destory
    ○ 鎖操作:
        § 加鎖:int pthread_mutex_lock(pthread_mutex_t *mutex)
        § 解鎖:int pthread_mutex_unlock(pthread_mutex_t *mutex)
        § 測(cè)試加鎖:int pthread_mutex_trylock(pthread_mutex_t *mutex)
? 條件鎖:為了保證不同線程之間有順序(通過條件控制)地完成某個(gè)流程
    ○ 等待方式:
        § 無條件等待:pthread_cond_wait()
        § 計(jì)時(shí)等待:pthread_cond_timedwait()
    ○ 激活條件:
        §  int pthread_cond_signal(pthread_cond_t *cond); 激活一個(gè)等待該條件的線程吸奴,存在多個(gè)等待線程時(shí)按入隊(duì)順序激活其中一個(gè)
        § int pthread_cond_broadcast(pthread_cond_t *cond);  激活所有等待線程

互斥鎖:

#include <pthread.h>
#include <stdio.h>
 
pthread_mutex_t mutex ;
void *print_msg(void *arg){
        int i=0;
        pthread_mutex_lock(&mutex);
        for(i=0;i<15;i++){
                printf("output : %d\n",i);
                usleep(100);
        }
        pthread_mutex_unlock(&mutex);
}
int main(int argc,char** argv){
        pthread_t id1;
        pthread_t id2;
        pthread_mutex_init(&mutex,NULL);
        pthread_create(&id1,NULL,print_msg,NULL);
        pthread_create(&id2,NULL,print_msg,NULL);
        pthread_join(id1,NULL);
        pthread_join(id2,NULL);
        pthread_mutex_destroy(&mutex);
        return 1;
}

條件鎖:

//一個(gè)生產(chǎn)者消費(fèi)者模型
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>

typedef struct node
{
    int num;
    struct node *next;
} node_t;

typedef node_t *list_t;
list_t head = NULL;
pthread_mutex_t mutex =
    PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond =
    PTHREAD_COND_INITIALIZER;

//消費(fèi)者線程
void *consume(void *arg)
{
    node_t *tmp;
    while (1)
    {
        //加鎖
        pthread_mutex_lock(&mutex); //對(duì)臨界變量加鎖
        if (head == NULL)           //如果頭部指向空,等待
            pthread_cond_wait(&cond, &mutex);
        tmp = head;        //將要?jiǎng)h除的節(jié)點(diǎn)賦值給中間值,然后頭指針指向下一個(gè)
        head = head->next; //
        //解鎖
        pthread_mutex_unlock(&mutex);
        //消費(fèi)tmp節(jié)點(diǎn)
        printf("consum:%d\n", tmp->num);
        free(tmp);
        tmp = NULL;
        sleep(rand() % 5);
    }
}

//生產(chǎn)者線程
void *product(void *arg)
{ //函數(shù)的格式void *(*start_routine) (void *)则奥,返回值是指針考润,參數(shù)也是
    node_t *n;
    while (1)
    {
        //生產(chǎn)一個(gè)新的節(jié)點(diǎn)
        n = (node_t *)malloc(sizeof(node_t));
        n->num = rand() % 1000 + 1;
        printf("p:%d\n", n->num);
        //加鎖
        pthread_mutex_lock(&mutex);
        //將新節(jié)點(diǎn)放入到鏈表的頭部
        n->next = head;
        head = n;
        //解鎖
        pthread_mutex_unlock(&mutex);
        //通知消費(fèi)者
        pthread_cond_signal(&cond);
        sleep(rand() % 5);
    }
}
int main(void)
{
    pthread_t pid, cid;
    //設(shè)置隨機(jī)數(shù)的種子
    srand(time(NULL));
    //創(chuàng)建兩個(gè)線程,用于生產(chǎn)者和消費(fèi)者
    pthread_create(&pid, NULL, product, NULL); //創(chuàng)建線程后即執(zhí)行該線程
    pthread_create(&cid, NULL, consume, NULL); //參數(shù)含義是(存放ID的緩存區(qū)读处,NULL缺省屬性糊治,線程的執(zhí)行函數(shù),函數(shù)的唯一參數(shù))
    //等待線程的匯合
    pthread_join(pid, NULL);
    pthread_join(cid, NULL);
    //銷毀mutex鎖
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末罚舱,一起剝皮案震驚了整個(gè)濱河市井辜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌馆匿,老刑警劉巖抑胎,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異渐北,居然都是意外死亡阿逃,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門赃蛛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恃锉,“玉大人,你說我怎么就攤上這事呕臂∑仆校” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵歧蒋,是天一觀的道長(zhǎng)土砂。 經(jīng)常有香客問我,道長(zhǎng)谜洽,這世上最難降的妖魔是什么萝映? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮序臂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘实束。我一直安慰自己奥秆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布咸灿。 她就那樣靜靜地躺著构订,像睡著了一般。 火紅的嫁衣襯著肌膚如雪避矢。 梳的紋絲不亂的頭發(fā)上鲫咽,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天签赃,我揣著相機(jī)與錄音谷异,去河邊找鬼分尸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛歹嘹,可吹牛的內(nèi)容都是我干的箩绍。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼尺上,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼材蛛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起怎抛,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤卑吭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后马绝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豆赏,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年富稻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掷邦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡椭赋,死狀恐怖抚岗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哪怔,我是刑警寧澤宣蔚,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站认境,受9級(jí)特大地震影響胚委,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜元暴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一篷扩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧茉盏,春花似錦鉴未、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至讶迁,卻和暖如春连茧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工啸驯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留客扎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓罚斗,卻偏偏與公主長(zhǎng)得像徙鱼,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子针姿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • ps: 這篇文章看資料時(shí)頭疼袱吆,寫起來時(shí)更頭疼,寫完了說實(shí)話也沒多大用距淫,充其量也就是多了解了一些鎖的內(nèi)容绞绒,也許扣字眼...
    前行的烏龜閱讀 1,521評(píng)論 0 5
  • 線程鎖 使用多線程能提高程序的執(zhí)行效率,但也同時(shí)也給程序帶來一些線程安全上面的問題榕暇,比如是數(shù)據(jù)競(jìng)爭(zhēng)關(guān)系(data ...
    struggle3g閱讀 2,178評(píng)論 1 2
  • 多線程需要一種互斥的機(jī)制來訪問共享資源蓬衡。 一、 互斥鎖 互斥鎖的意思是某一時(shí)刻只允許一個(gè)線程訪問某一資源拐揭。為了保證...
    doudo閱讀 722評(píng)論 0 5
  • 參考鏈接:http://smallbug-vip.iteye.com/blog/2275743 在多線程開發(fā)的過程...
    時(shí)之令閱讀 1,549評(píng)論 2 5
  • 題記:雖然有些事情的發(fā)生可能是你預(yù)料之中的撤蟆,但是當(dāng)它真正的發(fā)生了的時(shí)候,還是很難以接受的堂污,還是需要一點(diǎn)時(shí)間家肯,去緩和...
    LynnXYT閱讀 2,000評(píng)論 4 16