中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

中企網站建設app推廣軟件

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

目錄

一、概念

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

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

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

生產者與消費者模型


一、概念

概念:在多線程程序中,如果涉及到了對共享資源的操作,則有可能會導致數據二義性,而線程安全就指的是,就算對共享資源進行操作也不會導致數據二義

實現(xiàn):如何實現(xiàn)多線程中對共享資源的操作不會出問題

??????? 互斥:通過同一時間對資源訪問的唯一性,保證訪問安全

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

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

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

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

實現(xiàn)對共享資源的唯一訪問

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

??????? 本質:就是一個1/0計數器,通過0/1標記資源的訪問狀態(tài)(0-不可訪問、1-可訪問)

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

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

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

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

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

?互斥鎖的操作本身必須是安全的:互斥鎖本身計數器的操作時原子操作

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

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

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

所以對于鎖資源本身來說,計數器的操作必須是原子性的才可以。

有個指令類似于exchange,功能是交換指定寄存器與內存中的數據

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

??????? 2、將寄存器與內存中的數據進行互換

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

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

3)接口

互斥鎖類型變量????? pthread_mutex_t

初始化互斥鎖

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

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

訪問資源前加鎖

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

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

訪問資源后解鎖

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

釋放銷毀互斥鎖

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

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

4)代碼模擬

當不使用互斥鎖線程之間對同一變量的訪問情況如何?

#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 號票\n",pthread_self(), ticket);ticket--;}else{printf("%p:票完了,我的工作結束了\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ā)生了同一變量的多次出現(xiàn)。

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

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>int ticket = 100;
void *Scalper(void *arg)
{while(1){pthread_mutex_lock(arg);    // 訪問之前加鎖if(ticket > 0){usleep(10);printf("%p:我搶到了第 %d 號票\n",pthread_self(), ticket);ticket--;pthread_mutex_unlock(arg);    // 在所有有可能退出的地方解鎖}else{printf("%p:票完了,我的工作結束了\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); // 注意鎖資源通過線程創(chuàng)建第四個參數傳入入口函數內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),是一種因為資源爭搶不當導致程序流程卡死無法繼續(xù)向下推進的狀態(tài)。

多個線程對鎖資源的爭搶使用不當導致程序流程卡死,無法繼續(xù)向下推進的狀態(tài)

1、加鎖之后沒有釋放就退出,導致其他線程獲取不到鎖資源卡死

2、多鎖使用時,加鎖順序不當,線程1加鎖順序為AB,線程2加鎖順序為BA

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

??????? ① 互斥條件??????? 同一時間一把鎖只能被一個線程所獲取到

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

??????? ③ 請求與保持??????? 一個線程請求了A鎖之后請求B鎖,如果請求不到就不會釋放A鎖

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

死鎖的預防:破壞死鎖產生的必要條件

??????? ① 和 ② 無法修改

??????? 寫代碼時要注意:

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

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

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

避免:銀行家算法、死鎖檢測算法……

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

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

1)概念

同步:通過條件控制,保證資源訪問的合理性

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

原理:

??????? 線程1 獲取資源時進行判斷,如果線程不符合資源獲取條件,則調用阻塞接口進行阻塞

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

條件變量需要搭配互斥鎖來使用

舉例:

??????? 顧客 與 廚師 (消費者與生產者)

顧客來到柜臺,看到柜臺有飯則吃飯,否則阻塞

廚師來到柜臺,看到柜臺上沒有飯則做飯,否則阻塞

顧客:

??????? 0、加鎖(關門)

??????? 1、訪問柜臺有沒有飯

??????????????? 有飯則吃飯,沒有飯就阻塞

???????????? (這里阻塞時需要進行解鎖,否則廚師就無法訪問柜臺,也就無法做飯,產生死鎖)

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

??????? 2、吃飯

??????? 3、吃完了,再來一碗?????? 喚醒廚師

??????? 4、解鎖

廚師:

??????? 0、加鎖

??????? 1、訪問柜臺有沒有飯

??????? ??????? 沒飯則做飯,有飯則阻塞

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

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

??????? 2、做飯

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

??????? 4、解鎖

2)接口

定義條件變量:

??????? pthread_cond_t 條件變量的變量類型

初始化條件變量:

??????? 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 ) -- 有時長限制的阻塞

喚醒接口:

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

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

銷毀接口:

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

3)模擬實現(xiàn)

#include<stdio.h>
#include<pthread.h>int counter = 0;    // 定義柜臺狀態(tài) 0——沒飯   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);    // 沒飯則解鎖 并阻塞,等待喚醒,喚醒后加鎖}printf("真好吃,再來一碗\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)建對應線程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的銷毀pthread_cond_destroy(&cond);
}

?實現(xiàn)四個顧客四個廚師

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

#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("真好吃,再來一碗: %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];    // 定義四個顧客、四個廚師pthread_t cus_tid[4];int ret;for(int i = 0; i < 4; i++) // 創(chuàng)建這八個線程{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);
}

?生產者與消費者模型

生產者與消費者模型icon-default.png?t=N176http://t.csdn.cn/GvZlZ

http://www.risenshineclean.com/news/38093.html

相關文章:

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