亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

1、按照指定的順序輸出

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

foo1:打印step1, step3

foo2:打印step2

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

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

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

#include "csapp.c"


sem_t step1_done, step2_done;

void*  foo1() {
    printf("test1 is done\n");
    V(&step1_done);                  //step1執(zhí)行完畢了,那么foo2的阻塞就會被解開
    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);            //第二個參數(shù)為0:在線程之間進行, 第三個參數(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)者消費者模型

主要的就是在生產(chǎn)和消費函數(shù)中對于信號量的處理

錯誤實例:

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

    //將項目放進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);
}

如果我們在處理的時候先拿到 互斥鎖,可能就會引起死鎖

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

此時消費者同樣因為拿不到互斥鎖而被 block…

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

解決方法:

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

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

typedef struct sbuf{
    int *buf;               /*堆上開辟的內(nèi)存,用于存儲*/
    int n;                  /*cap of the buf*/
    int front;              //第一個item
    int rear;               //最后一個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) {
    //首先應該對信號量slots判斷,你生產(chǎn)者看中
    sem_wait(&sp->slots);
    sem_wait(&sp->mutex);

    //將項目放進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);       //我看上哪個格子的產(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)先)

  • 不會讓讀者進行等待的,除非現(xiàn)在的權(quán)限是寫者的
  • 也就是說讀者不會因為有一個寫者在等待

實現(xiàn):

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

每當寫者進入了臨界區(qū),就對w進行加鎖??,離開就解鎖。保證了任意時刻臨界區(qū)最多只能有一個寫者

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

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

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

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

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

您可能感興趣的文章:

相關文章

  • C++中引用(&)的用法與應用實例分析

    C++中引用(&)的用法與應用實例分析

    引用是C++引入的新語言特性,是C++常用的一個重要內(nèi)容之一,正確、靈活地使用引用,可以使程序簡潔、高效。故在本篇中我將對引用進行詳細討論,希望對大家更好地理解和使用引用起到拋磚引玉的作用
    2013-09-09
  • C語言文字藝術(shù)之數(shù)據(jù)輸入輸出

    C語言文字藝術(shù)之數(shù)據(jù)輸入輸出

    這篇文章主要介紹了C語言文字藝術(shù)之數(shù)據(jù)輸入輸出,C語言的語句用來向計算機系統(tǒng)發(fā)出操作指令。一條語句編寫完成經(jīng)過編譯后產(chǎn)生若干條機器指
    2022-07-07
  • C語言數(shù)據(jù)結(jié)構(gòu)中串的模式匹配

    C語言數(shù)據(jù)結(jié)構(gòu)中串的模式匹配

    這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)中串的模式匹配的相關資料,需要的朋友可以參考下
    2017-05-05
  • C++實現(xiàn)并優(yōu)化異常系統(tǒng)

    C++實現(xiàn)并優(yōu)化異常系統(tǒng)

    異常處理是C++的一項語言機制,用于在程序中處理異常事件,下面這篇文章主要給大家介紹了關于C++中異常的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • C語言 選擇排序算法詳解及實現(xiàn)代碼

    C語言 選擇排序算法詳解及實現(xiàn)代碼

    本文主要介紹C語言 選擇排序算法,這里對排序算法做了詳細說明,并附代碼示例,有需要的小伙伴可以參考下
    2016-08-08
  • C++中的復制構(gòu)造函數(shù)詳解

    C++中的復制構(gòu)造函數(shù)詳解

    今天小編就為大家分享一篇關于關于C++復制構(gòu)造函數(shù)的實現(xiàn)講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2021-09-09
  • C語言代碼實現(xiàn)簡易掃雷

    C語言代碼實現(xiàn)簡易掃雷

    這篇文章主要為大家詳細介紹了C語言代碼實現(xiàn)簡易掃雷,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • OpenCV reshape函數(shù)實現(xiàn)矩陣元素序列化

    OpenCV reshape函數(shù)實現(xiàn)矩陣元素序列化

    reshape函數(shù)是OpenCV中一個很有用的函數(shù),不僅可以改變矩陣的通道數(shù),還可以對矩陣元素進行序列化。本文將主要介紹如何通過reshape實現(xiàn)矩陣元素序列化,需要的小伙伴可以參考一下
    2021-12-12
  • C/C++語言中結(jié)構(gòu)體的內(nèi)存分配小例子

    C/C++語言中結(jié)構(gòu)體的內(nèi)存分配小例子

    當未用 #pragma 指令指定編譯器的對齊位數(shù)時,結(jié)構(gòu)體按最長寬度的數(shù)據(jù)成員的寬度對齊;當使用了 #pragma 指令指定編譯器的對齊位數(shù)時,結(jié)構(gòu)體按最長寬度的數(shù)據(jù)成員的寬度和 #pragma 指令指定的位數(shù)中的較小值對齊
    2013-10-10
  • Qt QFrame的具體使用

    Qt QFrame的具體使用

    本文主要介紹了Qt QFrame的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06

最新評論