91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

C語言并發編程模型實例分析

發布時間:2022-04-16 09:08:03 來源:億速云 閱讀:154 作者:iii 欄目:開發技術

這篇文章主要介紹“C語言并發編程模型實例分析”,在日常操作中,相信很多人在C語言并發編程模型實例分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C語言并發編程模型實例分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

1、按照指定的順序輸出

我們執行兩個線程:foo1foo2

foo1:打印step1, step3

foo2:打印step2

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

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

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

#include "csapp.c"


sem_t step1_done, step2_done;

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

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

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


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


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


    exit(0);

}

2、生產者消費者模型

主要的就是在生產和消費函數中對于信號量的處理

錯誤實例:

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

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

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

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

其他的生產者同樣也是沒有 互斥鎖被block…

解決方法:

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

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

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

    sem_t mutex;            //獲取臨界區的鎖
    sem_t slots;            //空槽數目
    sem_t items;            //已經生產了的數目
}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判斷,你生產者看中
    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);       //我看上哪個格子的產品了
    sem_wait(&sp->mutex);

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

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

3、讀寫鎖

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

  • 不會讓讀者進行等待的,除非現在的權限是寫者的

  • 也就是說讀者不會因為有一個寫者在等待

實現:

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

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

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

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

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

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

到此,關于“C語言并發編程模型實例分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

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

AI

眉山市| 元阳县| 汉川市| 庄河市| 漯河市| 华蓥市| 阿拉善盟| 修武县| 芦山县| 南部县| 青州市| 瑞昌市| 洛扎县| 五台县| 来宾市| 响水县| 桂林市| 金昌市| 佛冈县| 华坪县| 台中县| 神池县| 林甸县| 绍兴县| 来凤县| 内乡县| 光山县| 界首市| 亳州市| 平安县| 兴城市| 循化| 家居| 平谷区| 扶风县| 常宁市| 包头市| 玛多县| 灵璧县| 正宁县| 监利县|