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

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

幾十元做網(wǎng)站濰坊快速網(wǎng)站排名

幾十元做網(wǎng)站,濰坊快速網(wǎng)站排名,wordpress資源分享網(wǎng),手工制作小錢包一、臨界資源與臨界區(qū) 多線程會共享例如全局變量等資源&#xff0c;我們把會被多個執(zhí)行流訪問的資源稱為臨界資源&#xff0c;我們是通過代碼訪問臨界資源的&#xff0c;而我們訪問臨界資源的那部分代碼稱為臨界區(qū)。 實現(xiàn)一個搶票系統(tǒng) 只有一個線程搶票時 #include <ios…

一、臨界資源與臨界區(qū)

多線程會共享例如全局變量等資源,我們把會被多個執(zhí)行流訪問的資源稱為臨界資源,我們是通過代碼訪問臨界資源的,而我們訪問臨界資源的那部分代碼稱為臨界區(qū)。

實現(xiàn)一個搶票系統(tǒng)

只有一個線程搶票時

#include <iostream>
#include <vector>
#include <unistd.h>#include "Thread.hpp"int num = 10000; std::string GetThreadName()
{static int num = 1;char name[64];snprintf(name, sizeof(name), "thread-%d", num++);return name;
}void Ticket(std::string name)
{while(true){if(num > 0){usleep(1000);printf("%s get ticket: %d\n", name.c_str(), num);num--;}else{break;}}
}int main()
{std::string name1 = GetThreadName();Thread<std::string> t1(name1, Ticket, name1);t1.Start();t1.Join();return 0;
}

正常輸出,最終票數(shù)為0時退出。

但是當我們啟動多個線程同時搶票時,num就是臨界資源,使用num的那部分代碼就是臨界區(qū)

#include <iostream>
#include <vector>
#include <unistd.h>#include "Thread.hpp"int num = 10000; std::string GetThreadName()
{static int num = 1;char name[64];snprintf(name, sizeof(name), "thread-%d", num++);return name;
}void Ticket(std::string name)
{while(true){if(num > 0){usleep(1000);printf("%s get ticket: %d\n", name.c_str(), num);num--;}else{break;}}
}int main()
{std::string name1 = GetThreadName();Thread<std::string> t1(name1, Ticket, name1);std::string name2 = GetThreadName();Thread<std::string> t2(name2, Ticket, name2);std::string name3 = GetThreadName();Thread<std::string> t3(name3, Ticket, name3);std::string name4 = GetThreadName();Thread<std::string> t4(name4, Ticket, name4);t1.Start();t2.Start();t3.Start();t4.Start();t1.Join();t2.Join();t3.Join();t4.Join();return 0;
}

可以看到出現(xiàn)了0和負數(shù)的票數(shù),這是因為當票數(shù)只剩1時,有多個執(zhí)行流在同一時間通過了if判斷,使得能繼續(xù)進行減票操作。

vs下自減操作的反匯編,分為三步:先從內(nèi)存拿數(shù)據(jù),再把數(shù)據(jù)減1,最后把數(shù)據(jù)拷貝到內(nèi)存

多個執(zhí)行流同時訪問臨界資源例如自減操作,由于--操作不是原子性的(我們認為一條匯編指令是原子性的,是不會被中斷的。但--操作轉為匯編指令后,需要多條指令才能完成),當--操作執(zhí)行到一半切換到其他線程會導致數(shù)據(jù)不一致的問題。這種情況下需要通過鎖把臨界區(qū)保護起來,每次只讓一個執(zhí)行流訪問臨界資源,避免數(shù)據(jù)不一致問題。

互斥:任何時刻,互斥保證有且只有一個執(zhí)行流進入臨界區(qū),訪問臨界資源,通常對臨界資源起保護作用。

原子性:不會被任何調(diào)度機制打斷的操作,該操作只有兩態(tài),要么完成,要么未完成。

二、使用鎖的方法

1.創(chuàng)建鎖

如果定義一個全局的鎖,直接使用pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER用宏初始化。

如果定義一個局部鎖,要使用pthread_mutex_init方法創(chuàng)建,參數(shù)attr設為nullptr

2.加鎖解鎖

使用pthread_mutex_lock加鎖,傳遞鎖的地址,

解鎖用pthread_mutex_unlock

當我們使用鎖后,就能保證每次只有一個執(zhí)行流能訪問臨界資源。

#include <iostream>
#include <vector>
#include <unistd.h>#include "Thread.hpp"int num = 10000;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //定義一個全局鎖std::string GetThreadName()
{static int num = 1;char name[64];snprintf(name, sizeof(name), "thread-%d", num++);return name;
}void Ticket(std::string name)
{while(true){pthread_mutex_lock(&mutex); //加鎖if(num > 0){usleep(1000);printf("%s get ticket: %d\n", name.c_str(), num);num--;pthread_mutex_unlock(&mutex); //解鎖}else{pthread_mutex_unlock(&mutex); //解鎖break;}}
}int main()
{std::string name1 = GetThreadName();Thread<std::string> t1(name1, Ticket, name1);std::string name2 = GetThreadName();Thread<std::string> t2(name2, Ticket, name2);std::string name3 = GetThreadName();Thread<std::string> t3(name3, Ticket, name3);std::string name4 = GetThreadName();Thread<std::string> t4(name4, Ticket, name4);t1.Start();t2.Start();t3.Start();t4.Start();t1.Join();t2.Join();t3.Join();t4.Join();return 0;
}

結果正常,但是速度慢了很多,因為要不斷申請鎖和釋放鎖

加鎖解鎖的過程是安全的

三、可重入和線程安全

1.概念

線程安全:多個線程并發(fā)同一段代碼時,不會出現(xiàn)不同的結果。常見對全局變量或者靜態(tài)變量進行操作, 并且沒有鎖保護的情況下,會出現(xiàn)該問題。

重入:同一個函數(shù)被不同的執(zhí)行流調(diào)用,當前一個流程還沒有執(zhí)行完,就有其他的執(zhí)行流再次進入,我們稱之為重入。一個函數(shù)在重入的情況下,運行結果不會出現(xiàn)任何不同或者任何問題,則該函數(shù)被稱為可重入函數(shù),否則,是不可重入函數(shù)。

2.常見的線程不安全的情況

1.不保護共享變量的函數(shù)

2.函數(shù)狀態(tài)隨著被調(diào)用,狀態(tài)發(fā)生變化的函數(shù)

3.返回指向靜態(tài)變量指針的函數(shù)

4.調(diào)用線程不安全函數(shù)的函數(shù)

3.常見的線程安全的情況

1.調(diào)用了malloc/free函數(shù),因為malloc函數(shù)是用全局鏈表來管理堆的

2.調(diào)用了標準I/O庫函數(shù),標準I/O庫的很多實現(xiàn)都以不可重入的方式使用全局數(shù)據(jù)結構

3.可重入函數(shù)體內(nèi)使用了靜態(tài)的數(shù)據(jù)結構

4.常見可重入的情況

1.不使用全局變量或靜態(tài)變量

2.不使用用malloc或者new開辟出的空間

3.不調(diào)用不可重入函數(shù)不返回靜態(tài)或全局數(shù)據(jù),所有數(shù)據(jù)都有函數(shù)的調(diào)用者提供

4.使用本地數(shù)據(jù),或者通過制作全局數(shù)據(jù)的本地拷貝來保護全局數(shù)據(jù)

5.可重入與線程安全聯(lián)系

1.函數(shù)是可重入的,那就是線程安全的

2.函數(shù)是不可重入的,那就不能由多個線程使用,有可能引發(fā)線程安全問題

3.如果一個函數(shù)中有全局變量,那么這個函數(shù)既不是線程安全也不是可重入的。

6.可重入與線程安全區(qū)別

1.可重入函數(shù)是線程安全函數(shù)的一種

2.線程安全不一定是可重入的,而可重入函數(shù)則一定是線程安全的。

3.如果將對臨界資源的訪問加上鎖,則這個函數(shù)是線程安全的,但如果這個重入函數(shù)若鎖還未釋放則會產(chǎn)生 死鎖,因此是不可重入的。

四、死鎖

死鎖是指在一組進程中的各個進程均占有不會釋放的資源,但因互相申請被其他進程所站用不會釋放的資源而處于的一種永久等待狀態(tài)。

1.死鎖四個必要條件

1.互斥條件:一個資源每次只能被一個執(zhí)行流使用

2.請求與保持條件:一個執(zhí)行流因請求資源而阻塞時,對已獲得的資源保持不放

3.不剝奪條件: 一個執(zhí)行流已獲得的資源,在末使用完之前,不能強行剝奪

4.循環(huán)等待條件: 若干執(zhí)行流之間形成一種頭尾相接的循環(huán)等待資源的關系

2.避免死鎖

1.破壞死鎖的四個必要條件

2.加鎖順序一致

3.避免鎖未釋放的場景

4.資源一次性分配

3.避免死鎖算法

1.死鎖檢測算法

2.銀行家算法

一個鎖會造成死鎖嗎?

答案是會的,當一個線程申請完一個鎖,訪問完臨界資源后,接下來該釋放鎖了,但是代碼卻寫成了加鎖,這就會導致死鎖問題。

http://aloenet.com.cn/news/46821.html

相關文章:

  • 網(wǎng)站設置黑白色快速建站哪個平臺好
  • 新鄉(xiāng)網(wǎng)站優(yōu)化公司價格網(wǎng)絡服務包括哪些內(nèi)容
  • 拼多多cms網(wǎng)站怎么做今天新聞頭條最新消息
  • ps網(wǎng)站切圖教程南京seo關鍵詞優(yōu)化預訂
  • 四川網(wǎng)站建設價格為企業(yè)策劃一次網(wǎng)絡營銷活動
  • 黨建網(wǎng)站建設入黨外調(diào)函模板外貿(mào)網(wǎng)站優(yōu)化公司
  • 做網(wǎng)站要買什么中文搜索引擎排名
  • 用wordpress建站學什么網(wǎng)絡推廣經(jīng)驗
  • 成都新線加網(wǎng)站建設百度指數(shù)分是什么
  • 手機ppt制作軟件站群seo技巧
  • 網(wǎng)站開發(fā)女生可以做嗎太原首頁推廣
  • 大學網(wǎng)站建設工作總結aso網(wǎng)站
  • 淮北網(wǎng)站三合一建設百度官方網(wǎng)站網(wǎng)址
  • 煙臺網(wǎng)站制作公司網(wǎng)站發(fā)布與推廣方案
  • wordpress主題安裝說明seo主要做什么
  • wordpress 中介免費seo快速收錄工具
  • ui做網(wǎng)站實例廣告公司業(yè)務推廣
  • 蘇州公司網(wǎng)頁制作seo推廣專員工作好做嗎
  • 網(wǎng)站中的游戲是怎么做的無錫百度快速優(yōu)化排名
  • 寧波做網(wǎng)站定制客戶管理軟件crm排名
  • 建設網(wǎng)站軟件下載html做一個簡單的網(wǎng)頁
  • 常州網(wǎng)站建設推廣網(wǎng)絡營銷公司全網(wǎng)推廣公司
  • 做網(wǎng)站和自媒體哪個好seo全稱是什么意思
  • 做設計網(wǎng)站模塊的網(wǎng)站杭州網(wǎng)絡優(yōu)化公司排名
  • 做網(wǎng)站月度總結如何做品牌推廣方案
  • 嵌入式工程師月薪多少域名查詢seo
  • 有沒有網(wǎng)站可以做地圖seo關鍵詞快速排名介紹
  • 網(wǎng)站建設軟件的英文被忽悠去做網(wǎng)銷了
  • 網(wǎng)站子網(wǎng)頁怎么做網(wǎng)站怎么優(yōu)化關鍵詞
  • 汽車之家網(wǎng)站是怎么做的網(wǎng)絡營銷論文題目