国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

中企網(wǎng)站建設(shè)app推廣軟件

中企網(wǎng)站建設(shè),app推廣軟件,做邀請(qǐng)函好的網(wǎng)站,舊房改造室內(nèi)裝修設(shè)計(jì)公司目錄 一、概念 二、互斥鎖實(shí)現(xiàn)互斥 三、條件變量實(shí)現(xiàn)同步 銀行家算法 生產(chǎn)者與消費(fèi)者模型 一、概念 概念:在多線程程序中,如果涉及到了對(duì)共享資源的操作,則有可能會(huì)導(dǎo)致數(shù)據(jù)二義性,而線程安全就指的是,就算對(duì)共享…

目錄

一、概念

二、互斥鎖實(shí)現(xiàn)互斥

三、條件變量實(shí)現(xiàn)同步

????????銀行家算法

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


一、概念

概念:在多線程程序中,如果涉及到了對(duì)共享資源的操作,則有可能會(huì)導(dǎo)致數(shù)據(jù)二義性,而線程安全就指的是,就算對(duì)共享資源進(jìn)行操作也不會(huì)導(dǎo)致數(shù)據(jù)二義

實(shí)現(xiàn):如何實(shí)現(xiàn)多線程中對(duì)共享資源的操作不會(huì)出問(wèn)題

??????? 互斥:通過(guò)同一時(shí)間對(duì)資源訪問(wèn)的唯一性,保證訪問(wèn)安全

?????????????? ? 互斥的實(shí)現(xiàn):互斥鎖(讀寫(xiě)鎖、自旋鎖...)

??????? 同步:通過(guò)條件控制,讓多執(zhí)行對(duì)資源的獲取更加合理

???????????????? 同步實(shí)現(xiàn):條件變量、信號(hào)量

二、互斥鎖實(shí)現(xiàn)互斥

實(shí)現(xiàn)對(duì)共享資源的唯一訪問(wèn)

1)互斥鎖實(shí)現(xiàn)互斥的原理

??????? 本質(zhì):就是一個(gè)1/0計(jì)數(shù)器,通過(guò)0/1標(biāo)記資源的訪問(wèn)狀態(tài)(0-不可訪問(wèn)、1-可訪問(wèn))

?????????????????? 在訪問(wèn)資源之前進(jìn)行加鎖(通過(guò)狀態(tài)判斷是否可訪問(wèn),不可訪問(wèn)則阻塞)

?????????????????? 在訪問(wèn)資源之后進(jìn)行解鎖(將資源狀態(tài)置為可訪問(wèn)狀態(tài),喚醒其他阻塞的線程)

????????也有另一種理解:訪問(wèn)資源之前加鎖(獲取鎖資源-獲取不到就阻塞)

???????????????????????????? ????????訪問(wèn)完畢解鎖(歸還鎖資源)

??????? 多個(gè)線程想要實(shí)現(xiàn)互斥,就必須訪問(wèn)同一個(gè)鎖才可以,也就意味著鎖也是一個(gè)共享資源

?互斥鎖的操作本身必須是安全的:互斥鎖本身計(jì)數(shù)器的操作時(shí)原子操作

2)互斥鎖如何實(shí)現(xiàn)自身操作安全的原理

?我們知道內(nèi)存與cpu之間的數(shù)據(jù)傳輸:當(dāng)進(jìn)行加鎖操作時(shí),先將鎖中的1置入cpu(先將變量數(shù)據(jù)從內(nèi)存加載到cpu)然后才能從cpu中對(duì)數(shù)據(jù)進(jìn)行處理(轉(zhuǎn)化為0)然后在從cpu中將數(shù)據(jù)加載到內(nèi)存指定位置(完成將1替換為0)

然而這樣一種操作就會(huì)產(chǎn)生問(wèn)題,如果1從內(nèi)存加載到cpu還沒(méi)有將處理后的0加載回內(nèi)存時(shí),這時(shí)切換其他線程運(yùn)行訪問(wèn)到的鎖資源仍然為1,就會(huì)繼續(xù)進(jìn)行加鎖,這無(wú)疑是致命的。

所以對(duì)于鎖資源本身來(lái)說(shuō),計(jì)數(shù)器的操作必須是原子性的才可以。

有個(gè)指令類(lèi)似于exchange,功能是交換指定寄存器與內(nèi)存中的數(shù)據(jù)

??????? 1、先將指定寄存器中的值修改為0,

??????? 2、將寄存器與內(nèi)存中的數(shù)據(jù)進(jìn)行互換

??????? 3、判斷是否符合獲取鎖的條件或者說(shuō)判斷是否能夠加鎖

?這樣使用exchange指令就可以實(shí)現(xiàn)計(jì)數(shù)器操作為原子操作。

3)接口

互斥鎖類(lèi)型變量????? pthread_mutex_t

初始化互斥鎖

??????? int pthread_mutex_init(pthread_mutex_t *mutex,? pthread_mutexattr_t *attr)

??????? ????????mutex:互斥鎖變量的地址??????? attr:互斥鎖變量屬性(通常置NULL)

訪問(wèn)資源前加鎖

??????? int pthread_mutex_lock(pthread_mutex_t *mutex)??????? 阻塞加鎖(老實(shí)人)

??????? int pthread_mutex_trylock(pthread_mutex_t *mutex)??????? 非阻塞加鎖(海王)

訪問(wèn)資源后解鎖

??????? int pthread_mutex_unlock(pthread_mutex_t *mutex)

釋放銷(xiāo)毀互斥鎖

??????? int pthread_mutex_destroy(pthread_mutex_t *mutex)

??????? pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER (這種初始化不需要銷(xiāo)毀)

4)代碼模擬

當(dāng)不使用互斥鎖線程之間對(duì)同一變量的訪問(wèn)情況如何?

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>int ticket = 100;
void *Scalper(void *arg)
{while(1){if(ticket > 0){usleep(10);printf("%p:我搶到了第 %d 號(hào)票\n",pthread_self(), ticket);ticket--;}else{printf("%p:票完了,我的工作結(jié)束了\n", pthread_self());break;}}return NULL;
}
int main()
{pthread_t tid[4];for(int i = 0; i < 4; i++){int ret = pthread_create(&tid[i], NULL, Scalper, NULL);if(ret != 0){perror("create error");return -1;}}for(int i = 0; i < 4; i++){pthread_join(tid[i], NULL);}return 0;
}

發(fā)現(xiàn)出現(xiàn)了很多意外情況,重復(fù)、負(fù)數(shù)票號(hào),

為什么呢?就是因?yàn)槊總€(gè)線程之間訪問(wèn)同一變量,一個(gè)線程還正對(duì)變量進(jìn)行操作的時(shí)候另一個(gè)線程也進(jìn)行操作,于是就發(fā)生了同一變量的多次出現(xiàn)。

?使用互斥鎖保護(hù)臨界區(qū)

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>int ticket = 100;
void *Scalper(void *arg)
{while(1){pthread_mutex_lock(arg);    // 訪問(wèn)之前加鎖if(ticket > 0){usleep(10);printf("%p:我搶到了第 %d 號(hào)票\n",pthread_self(), ticket);ticket--;pthread_mutex_unlock(arg);    // 在所有有可能退出的地方解鎖}else{printf("%p:票完了,我的工作結(jié)束了\n", pthread_self());pthread_mutex_unlock(arg);    // 在所有有可能退出的地方解鎖break;}usleep(1);}return NULL;
}
int main()
{pthread_mutex_t mutex;    // 定義鎖變量 mutexpthread_mutex_init(&mutex, NULL);    // 初始化鎖資源pthread_t tid[4];for(int i = 0; i < 4; i++){int ret = pthread_create(&tid[i], NULL, Scalper, &mutex); // 注意鎖資源通過(guò)線程創(chuàng)建第四個(gè)參數(shù)傳入入口函數(shù)內(nèi)if(ret != 0){perror("create error");return -1;}}for(int i = 0; i < 4; i++){pthread_join(tid[i], NULL);}return 0;
}

5)死鎖

死鎖是一種狀態(tài),是一種因?yàn)橘Y源爭(zhēng)搶不當(dāng)導(dǎo)致程序流程卡死無(wú)法繼續(xù)向下推進(jìn)的狀態(tài)。

多個(gè)線程對(duì)鎖資源的爭(zhēng)搶使用不當(dāng)導(dǎo)致程序流程卡死,無(wú)法繼續(xù)向下推進(jìn)的狀態(tài)

1、加鎖之后沒(méi)有釋放就退出,導(dǎo)致其他線程獲取不到鎖資源卡死

2、多鎖使用時(shí),加鎖順序不當(dāng),線程1加鎖順序?yàn)锳B,線程2加鎖順序?yàn)锽A

發(fā)生死鎖的必要條件

??????? ① 互斥條件??????? 同一時(shí)間一把鎖只能被一個(gè)線程所獲取到

??????? ② 不可剝奪條件??????? 一個(gè)線程加的鎖,只能自己釋放,其他線程無(wú)法釋放

??????? ③ 請(qǐng)求與保持??????? 一個(gè)線程請(qǐng)求了A鎖之后請(qǐng)求B鎖,如果請(qǐng)求不到就不會(huì)釋放A鎖

??????? ④ 環(huán)路等待??????? 線程1加了A鎖后請(qǐng)求B鎖,線程2加了B鎖后請(qǐng)求A鎖

死鎖的預(yù)防:破壞死鎖產(chǎn)生的必要條件

??????? ① 和 ② 無(wú)法修改

??????? 寫(xiě)代碼時(shí)要注意:

??????? 1、線程之間的加解鎖順序盡量一致 -- 盡可能預(yù)防環(huán)路等待

??????? 2、采用非阻塞加鎖,如果加不上鎖,則把已經(jīng)加上的鎖釋放 -- 破壞請(qǐng)求與保持

??????????????? (請(qǐng)求不到新的,則釋放已有的)

避免:銀行家算法、死鎖檢測(cè)算法……

銀行家算法http://t.csdn.cn/1YxZj

三、條件變量實(shí)現(xiàn)同步

1)概念

同步:通過(guò)條件控制,保證資源訪問(wèn)的合理性

條件變量:主要是一個(gè)pcb等待隊(duì)列,以及喚醒和阻塞線程的接口

原理:

??????? 線程1 獲取資源時(shí)進(jìn)行判斷,如果線程不符合資源獲取條件,則調(diào)用阻塞接口進(jìn)行阻塞

??????? 線程2 促使資源獲取條件滿(mǎn)足之后(生產(chǎn)資源),通過(guò)喚醒接口喚醒阻塞的線程

條件變量需要搭配互斥鎖來(lái)使用

舉例:

??????? 顧客 與 廚師 (消費(fèi)者與生產(chǎn)者)

顧客來(lái)到柜臺(tái),看到柜臺(tái)有飯則吃飯,否則阻塞

廚師來(lái)到柜臺(tái),看到柜臺(tái)上沒(méi)有飯則做飯,否則阻塞

顧客:

??????? 0、加鎖(關(guān)門(mén))

??????? 1、訪問(wèn)柜臺(tái)有沒(méi)有飯

??????????????? 有飯則吃飯,沒(méi)有飯就阻塞

???????????? (這里阻塞時(shí)需要進(jìn)行解鎖,否則廚師就無(wú)法訪問(wèn)柜臺(tái),也就無(wú)法做飯,產(chǎn)生死鎖)

??????????????? 阻塞則需先解鎖,再阻塞,被喚醒之后再加鎖

??????? 2、吃飯

??????? 3、吃完了,再來(lái)一碗?????? 喚醒廚師

??????? 4、解鎖

廚師:

??????? 0、加鎖

??????? 1、訪問(wèn)柜臺(tái)有沒(méi)有飯

??????? ??????? 沒(méi)飯則做飯,有飯則阻塞

??????????????? (這里是有飯就需要解鎖,讓顧客能夠吃飯,否則會(huì)死鎖)

??????????????? 阻塞需先解鎖,再阻塞,被喚醒后加鎖

??????? 2、做飯

??????? 3、做好了,喚醒顧客

??????? 4、解鎖

2)接口

定義條件變量:

??????? pthread_cond_t 條件變量的變量類(lèi)型

初始化條件變量:

??????? pthread_cond_t cond_init (pthread_cond_t *cond, pthread_condattr_t *attr);

阻塞接口:條件變量是搭配互斥鎖一起使用的,就體現(xiàn)在阻塞這一步

????????int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) -- 阻塞接口

??????? int pthread_cond_timewait(pthread_cond_t *cond, pthread_mutex_t *mutex,

????????????????????????????????????????????????? struct timespec *t ) -- 有時(shí)長(zhǎng)限制的阻塞

喚醒接口:

??????? int pthread_cond_signal(pthread_cond_t *cond)??????? 喚醒至少一個(gè)阻塞隊(duì)列中的線程

??????? int pthread_cond_broadcast(pthread_cond_t *cond)??????? 喚醒等待隊(duì)列中所有的線程

銷(xiāo)毀接口:

??????? int pthread_cond_destroy(pthread_cond_t *cond)

3)模擬實(shí)現(xiàn)

#include<stdio.h>
#include<pthread.h>int counter = 0;    // 定義柜臺(tái)狀態(tài) 0——沒(méi)飯   1——有飯 
pthread_mutex_t mutex;    // 初始化鎖
pthread_cond_t cond;    // 初始化條件變量void* customer(void *arg)
{while(1){pthread_mutex_lock(&mutex);    // 先加鎖if(counter==0){pthread_cond_wait(&cond, &mutex);    // 沒(méi)飯則解鎖 并阻塞,等待喚醒,喚醒后加鎖}printf("真好吃,再來(lái)一碗\n");counter = 0;pthread_cond_signal(&cond);    // 吃完了喚醒廚師做飯pthread_mutex_unlock(&mutex);    // 解鎖}
}void* cook(void *arg)
{while(1){pthread_mutex_lock(&mutex);    // 加鎖if(counter == 1){pthread_cond_wait(&cond, &mutex);    // 有飯則 解鎖并阻塞,等待喚醒,喚醒后加鎖}printf("你的飯好了\n");counter = 1;pthread_cond_signal(&cond);    // 飯做好了喚醒顧客吃飯pthread_mutex_unlock(&mutex);    // 解鎖}
}int main()
{pthread_mutex_init(&mutex, NULL);    // 初始化定義mutex 和 condpthread_cond_init(&cond, NULL);pthread_t cook_tid;    // 初始化定義線程ID(顧客和廚師)pthread_t cus_tid;int ret;ret = pthread_create(&cook_tid, NULL, cook, NULL);    // 分別創(chuàng)建對(duì)應(yīng)線程if(ret != 0){perror("create error");return -1;}ret = pthread_create(&cus_tid, NULL, customer, NULL);if(ret != 0){perror("create error");return -1;}pthread_join(cook_tid, NULL);    // 執(zhí)行線程等待pthread_join(cus_tid, NULL);pthread_mutex_destroy(&mutex);    // 執(zhí)行mutex與cond的銷(xiāo)毀pthread_cond_destroy(&cond);
}

?實(shí)現(xiàn)四個(gè)顧客四個(gè)廚師

在同步實(shí)現(xiàn)的代碼中,如果存在多種角色,就應(yīng)該定義多個(gè)條件變量,各自處于各自的pcb等待隊(duì)列中。

#include<stdio.h>
#include<pthread.h>int counter = 0;
pthread_mutex_t mutex;
pthread_cond_t cond_cus;    // 使用不同的條件變量,防止死鎖
pthread_cond_t cond_cook;
void* customer(void *arg)
{while(1){pthread_mutex_lock(&mutex);while(counter <= 0){pthread_cond_wait(&cond_cus, &mutex);}printf("真好吃,再來(lái)一碗: %d\n",counter);counter--;pthread_cond_signal(&cond_cook);pthread_mutex_unlock(&mutex);}
}void* cook(void *arg)
{while(1){pthread_mutex_lock(&mutex);while(counter > 0){pthread_cond_wait(&cond_cook, &mutex);}printf("你的飯好了:%d\n", counter);counter++;pthread_cond_signal(&cond_cus);pthread_mutex_unlock(&mutex);}
}int main()
{pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond_cus, NULL);pthread_cond_init(&cond_cook, NULL);pthread_t cook_tid[4];    // 定義四個(gè)顧客、四個(gè)廚師pthread_t cus_tid[4];int ret;for(int i = 0; i < 4; i++) // 創(chuàng)建這八個(gè)線程{ret = pthread_create(&cook_tid[i], NULL, cook, NULL);if(ret != 0){perror("create error");return -1;}ret = pthread_create(&cus_tid[i], NULL, customer, NULL);if(ret != 0){perror("create error");return -1;}}pthread_join(cook_tid[0], NULL);pthread_join(cus_tid[0], NULL);pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond_cook);pthread_cond_destroy(&cond_cus);
}

?生產(chǎn)者與消費(fèi)者模型

生產(chǎn)者與消費(fèi)者模型icon-default.png?t=N176http://t.csdn.cn/GvZlZ

http://m.aloenet.com.cn/news/38093.html

相關(guān)文章:

  • 做兼職的網(wǎng)站 知乎如何制作視頻網(wǎng)站
  • 委托設(shè)計(jì)網(wǎng)站 要注意哪些問(wèn)題哈爾濱關(guān)鍵詞排名工具
  • 杭州網(wǎng)站搜索排名國(guó)內(nèi)建站平臺(tái)
  • 做一個(gè)個(gè)人網(wǎng)站多少錢(qián)企業(yè)網(wǎng)站快速建站
  • 那里可以做旅游網(wǎng)站的嗎我們公司在做網(wǎng)站推廣
  • 線上線下購(gòu)物商城系統(tǒng)衡陽(yáng)seo快速排名
  • 國(guó)內(nèi)做的比較好的網(wǎng)站360優(yōu)化大師
  • 網(wǎng)站的透明圖片怎么做網(wǎng)絡(luò)服務(wù)主要包括
  • 網(wǎng)站開(kāi)發(fā)定義名稱(chēng)app優(yōu)化推廣
  • 怎么做網(wǎng)站推廣臨沂關(guān)鍵詞排名手機(jī)優(yōu)化軟件
  • 做網(wǎng)站用c語(yǔ)言可以嗎某個(gè)網(wǎng)站seo分析實(shí)例
  • 電腦版和手機(jī)版網(wǎng)站怎么做的營(yíng)銷(xiāo)推廣策劃方案范文
  • 昆明免費(fèi)網(wǎng)站制作南昌seo技術(shù)外包
  • 鄭州公共住宅建設(shè)投資有限公司網(wǎng)站一站式媒體發(fā)稿平臺(tái)
  • 1000學(xué)習(xí)做網(wǎng)站貴嗎搜索關(guān)鍵詞推薦
  • 網(wǎng)站建設(shè)報(bào)價(jià)明細(xì)表seo優(yōu)化運(yùn)營(yíng)
  • 廈門(mén)建站服務(wù)百度付費(fèi)推廣的費(fèi)用
  • 自助建站門(mén)戶(hù)網(wǎng)站東莞網(wǎng)絡(luò)優(yōu)化公司
  • 買(mǎi)模板建設(shè)網(wǎng)站亞馬遜關(guān)鍵詞工具哪個(gè)最準(zhǔn)
  • 電商 做圖 網(wǎng)站網(wǎng)站數(shù)據(jù)分析
  • 平東網(wǎng)站建設(shè)江北seo綜合優(yōu)化外包
  • 網(wǎng)頁(yè)游戲網(wǎng)站模板外貿(mào)平臺(tái)
  • 重慶房地產(chǎn)新聞上海網(wǎng)站seoseodian
  • 衡陽(yáng)有線寬帶網(wǎng)站怎么做app推廣
  • 南京網(wǎng)站制作設(shè)計(jì)公司尋找客戶(hù)的12種方法
  • 企業(yè)寬帶可以做網(wǎng)站嗎安卓?jī)?yōu)化大師手機(jī)版下載
  • 免費(fèi)直播網(wǎng)站開(kāi)發(fā)seo關(guān)鍵詞優(yōu)化排名
  • 站長(zhǎng)工具亞洲中文精品軟文推廣一般發(fā)布在哪些平臺(tái)
  • 南京網(wǎng)站建設(shè)蘇icp備蘭州正規(guī)seo整站優(yōu)化
  • 上海市住房與城鄉(xiāng)建設(shè)管理委員會(huì)網(wǎng)站網(wǎng)絡(luò)營(yíng)銷(xiāo)咨詢(xún)公司