最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言通過案例講解并發(fā)編程模型

 更新時(shí)間:2022年04月15日 16:59:05   作者:炸毛瘋兔  
所謂并發(fā)編程是指在一臺(tái)處理器上“同時(shí)”處理多個(gè)任務(wù)。并發(fā)是在同一實(shí)體上的多個(gè)事件。多個(gè)事件在同一時(shí)間間隔發(fā)生,下面我們根據(jù)樣例來理解

下面代碼、思路等來源于b站郭郭 和CSAPP樣例,同時(shí)希望大家好好讀一下CSAPP的內(nèi)容,真的講的很好

1、按照指定的順序輸出

我們執(zhí)行兩個(gè)線程:foo1foo2

foo1:打印step1, step3

foo2:打印step2

請(qǐng)用并發(fā)使得按照1 2 3 的順序輸出

答:首先兩個(gè)線程執(zhí)行順序不可預(yù)判,我們必須保證打印step2之前step1就打印好了,因此需要阻塞一下step2,實(shí)現(xiàn)的方式是初始化sem為0,只有打印完step1后(然后進(jìn)行解鎖,V操作)step2才能執(zhí)行

同理,只有打印完step2后才解開阻塞step3的鎖,具體看代碼實(shí)現(xiàn)就明白了

#include "csapp.c"


sem_t step1_done, step2_done;

void*  foo1() {
    printf("test1 is done\n");
    V(&step1_done);                  //step1執(zhí)行完畢了,那么foo2的阻塞就會(huì)被解開
    P(&step2_done);                  //測試是否step2執(zhí)行完畢,
    printf("test3 is done\n");
    return NULL;
}

void* foo2() {
    P(&step1_done);
    printf("test2 is done\n");
    V(&step2_done);                  //step2執(zhí)行完畢,解開打印step的鎖
    return NULL;
}

int main()
{
    pthread_t tid1, tid2;
    Sem_init(&step1_done, 0, 0);            //第二個(gè)參數(shù)為0:在線程之間進(jìn)行, 第三個(gè)參數(shù)初始化都為零
    Sem_init(&step2_done, 0, 0);


    Pthread_create(&tid1, NULL, foo1, NULL);
    Pthread_create(&tid2, NULL, foo2, NULL);


    //保證線程執(zhí)行完畢之后主線程才退出,否則線程都執(zhí)行不了了
    Pthread_join(tid1, NULL);
    Pthread_join(tid2, NULL);


    exit(0);

}

2、生產(chǎn)者消費(fèi)者模型

主要的就是在生產(chǎn)和消費(fèi)函數(shù)中對(duì)于信號(hào)量的處理

錯(cuò)誤實(shí)例:

void sbuf_insert(subf_t* sp, int item) {
    sem_wait(&sp->mutex);
  	sem_wait(&sp->slots);

    //將項(xiàng)目放進(jìn)buf中
    sp->buf[(++sp->rear) % (sp->n)] = item;

    sem_post(&sp->items);
    sem_post(&sp->mutex);

}


void sbuf_remove(sbuf_t* sp) {
  sem_wait(&sp->mutex);
  sem_wait(&sp->items);
  
  
  //do works
  
  sem_post(&sp->slots);
  sem_post(&sp->mutex);
}

如果我們?cè)谔幚淼臅r(shí)候先拿到 互斥鎖,可能就會(huì)引起死鎖

假設(shè)現(xiàn)在buf是滿的,生產(chǎn)者拿到了互斥鎖,但是自己因?yàn)闆]有空閑被 block…

此時(shí)消費(fèi)者同樣因?yàn)槟貌坏交コ怄i而被 block…

其他的生產(chǎn)者同樣也是沒有 互斥鎖被block…

解決方法:

比較簡單,調(diào)換一下順序就好了。相當(dāng)于我們生產(chǎn)者、消費(fèi)者在進(jìn)行的時(shí)候 明確我到底要操控哪個(gè)格子 然后再拿mutex??

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>

typedef struct sbuf{
    int *buf;               /*堆上開辟的內(nèi)存,用于存儲(chǔ)*/
    int n;                  /*cap of the buf*/
    int front;              //第一個(gè)item
    int rear;               //最后一個(gè)item

    sem_t mutex;            //獲取臨界區(qū)的鎖
    sem_t slots;            //空槽數(shù)目
    sem_t items;            //已經(jīng)生產(chǎn)了的數(shù)目
}subf_t;

void sbuf_init(subf_t* sp, int n) {
    sp->n     = n;
    sp->buf   = static_cast<int *>(calloc(n, sizeof(int)));
    sp->front = 0;
    sp->rear  = 0;

    sem_init(&sp->mutex, 0, 1);
    sem_init(&sp->slots, 0, n);
    sem_init(&sp->items, 0, 0);
}

void sbuf_deinit(subf_t*sp) {
    free(sp->buf);
}


void sbuf_insert(subf_t* sp, int item) {
    //首先應(yīng)該對(duì)信號(hào)量slots判斷,你生產(chǎn)者看中
    sem_wait(&sp->slots);
    sem_wait(&sp->mutex);

    //將項(xiàng)目放進(jìn)buf中
    sp->buf[(++sp->rear) % (sp->n)] = item;


    //CSAPP中提到,解鎖的順序一般是和加鎖的順序是相反的
    sem_post(&sp->mutex);
    sem_post(&sp->items);
}

int  sbuf_remove(subf_t* sp) {
    int item;
    sem_wait(&sp->items);       //我看上哪個(gè)格子的產(chǎn)品了
    sem_wait(&sp->mutex);

    item = sp->buf[(++sp->front) % (sp->n)];

    sem_post(&sp->mutex);
    sem_post(&sp->slots);
    return item;
}

3、讀寫鎖

第一類讀者、寫者問題(讀者優(yōu)先)

  • 不會(huì)讓讀者進(jìn)行等待的,除非現(xiàn)在的權(quán)限是寫者的
  • 也就是說讀者不會(huì)因?yàn)橛幸粋€(gè)寫者在等待

實(shí)現(xiàn):

信號(hào)量:w維護(hù)著對(duì)于critical section的訪問, mutex維護(hù)這對(duì)于共享變量readcnt(當(dāng)前在臨界區(qū)的讀者的數(shù)量)的訪問

每當(dāng)寫者進(jìn)入了臨界區(qū),就對(duì)w進(jìn)行加鎖??,離開就解鎖。保證了任意時(shí)刻臨界區(qū)最多只能有一個(gè)寫者

只有第一個(gè)讀者進(jìn)入的時(shí)候?qū)加鎖,最后一個(gè)才釋放,那么只要還有一個(gè)讀者在,其他任意的讀者就能夠無障礙的進(jìn)入,同樣會(huì)導(dǎo)致 寫者饑餓

int readcnt = 0;
sem_t ,mutex = 1, w = 1;

void reader() {
  while (1) {
    P(&mutex);
    readcnt++;
    if (readcnt == 1) 	//第一個(gè)進(jìn)入的讀者
      P(&w);						//上鎖,寫者不能寫了
    V(&mutex);					//解開對(duì)于readcnt的保護(hù)鎖
    
    /*
    		臨界區(qū)的工作
    
    */
    
    P(&mutex);
    readcnt--;
    if (readcnt == 0) 
      V(&w);								//最后一個(gè)讀者了, 解開阻塞寫者的鎖
    V(&mutex);							//解開對(duì)readcnt的保護(hù)鎖
  }
}

void writer() {
  while (1) {
    P(&w);
    
    /*
    	臨界區(qū)工作
    
    */
    V(&w);
  }
}

到此這篇關(guān)于C語言通過案例講解并發(fā)編程模型的文章就介紹到這了,更多相關(guān)C語言 并發(fā)編程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • C++頭文件algorithm中的函數(shù)功能詳解

    C++頭文件algorithm中的函數(shù)功能詳解

    這篇文章主要介紹了C++頭文件algorithm中的函數(shù)功能詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • C語言遞歸在實(shí)踐題目中應(yīng)用詳解

    C語言遞歸在實(shí)踐題目中應(yīng)用詳解

    遞歸是C語言中非常重要的知識(shí)點(diǎn),其中的大事化小等思想對(duì)初學(xué)C語言的小伙伴來說不是很友好,因此我整理了遞歸的經(jīng)典題目并向外拓展,給你全面的介紹,重新認(rèn)識(shí)遞歸
    2022-05-05
  • C++中Cbitmap,HBitmap,Bitmap區(qū)別及聯(lián)系

    C++中Cbitmap,HBitmap,Bitmap區(qū)別及聯(lián)系

    這篇文章主要介紹了C++中Cbitmap,HBitmap,Bitmap區(qū)別及聯(lián)系的相關(guān)資料,需要的朋友可以參考下
    2015-06-06
  • C#?CLR學(xué)習(xí)?C++使用namespace實(shí)例詳解

    C#?CLR學(xué)習(xí)?C++使用namespace實(shí)例詳解

    這篇文章主要為大家介紹了C#?CLR學(xué)習(xí)?C++使用namespace實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • C++實(shí)現(xiàn)圖書管理系統(tǒng)源碼

    C++實(shí)現(xiàn)圖書管理系統(tǒng)源碼

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)圖書管理系統(tǒng)源碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 華為面試題數(shù)字大小寫轉(zhuǎn)換

    華為面試題數(shù)字大小寫轉(zhuǎn)換

    一個(gè)四位數(shù),如1024,1004,打印出他們的中文形式,如果一千零二十四,一千零四,大家參考使用吧
    2013-12-12
  • C語言實(shí)現(xiàn)猜數(shù)字游戲的兩種方法

    C語言實(shí)現(xiàn)猜數(shù)字游戲的兩種方法

    猜數(shù)字小游戲是我們大多數(shù)人學(xué)習(xí)C語言時(shí)都會(huì)了解到的一個(gè)有趣的C語言小游戲,本文就詳細(xì)的介紹一下,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 餐館點(diǎn)菜系統(tǒng)C語言源代碼

    餐館點(diǎn)菜系統(tǒng)C語言源代碼

    這篇文章主要為大家詳細(xì)介紹了餐館點(diǎn)菜系統(tǒng)C語言源代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • Visual Studio 2019下配置 CUDA 10.1 + TensorFlow-GPU 1.14.0

    Visual Studio 2019下配置 CUDA 10.1 + TensorFlow-GPU 1.14.0

    這篇文章主要介紹了Visual Studio 2019下配置 CUDA 10.1 + TensorFlow-GPU 1.14.0,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • C++ 11和C++98相比有哪些新特性

    C++ 11和C++98相比有哪些新特性

    C++11標(biāo)準(zhǔn)提供了許多有用的新特性。這篇文章特別針對(duì)使C++11和C++98相比看上去像一門新語言的特性
    2017-03-03

最新評(píng)論

扎鲁特旗| 上栗县| 虞城县| 堆龙德庆县| 石渠县| 辽宁省| 巴林左旗| 锦州市| 贡山| 常州市| 海林市| 曲沃县| 健康| 若尔盖县| 江门市| 长武县| 乐业县| 汶上县| 会泽县| 明光市| 通州区| 通山县| 扬州市| 屯门区| 上饶县| 乌苏市| 桐柏县| 无极县| 乐陵市| 张家界市| 卓资县| 辰溪县| 永靖县| 土默特右旗| 清原| 汝南县| 电白县| 安塞县| 阜平县| 新巴尔虎左旗| 拉萨市|