国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

線程間互斥-mutex互斥鎖和lock_guard

這篇具有很好參考價值的文章主要介紹了線程間互斥-mutex互斥鎖和lock_guard。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

要點

  • 鎖+雙重判斷的技法

  • 竟態(tài)條件:多線程程序執(zhí)行的結果一致,不會隨著CPU對線程不同的調用順序

線程間安全實例——3個窗口同時賣票

線程不安全的代碼如下

int ticketCount = 100; // 100張車票
// 模擬10個窗口同時賣票
void sellTicket(int index)
{
	while (ticketCount > 0)
	{
		//cout << "窗口:" << index << "賣出第:" << ticketCount << "張票" << endl;
		cout << ticketCount << endl; // 打印當前剩余票數(shù)
		ticketCount--;
		std::this_thread::sleep_for(std::chrono::milliseconds(10));
	}
}
int main()
{
	list<std::thread> tlist;
	for (int i = 1; i <= 3; ++i)
	{
		tlist.push_back(std::thread(sellTicket, i));
	}

	for (std::thread& t : tlist)
	{
		t.join();
	}

	cout << "所有窗口賣票結束!" << endl;
	return	0;
}

輸出的部分結果里有很多重復的數(shù)字,相當于同一張票被賣出多次,原因在于

ticketCount–; 是線程不安全的,理由如下

線程間互斥-mutex互斥鎖和lock_guard

某一時刻ticketCount = 99,thread1此時調用ticketCount–,執(zhí)行到sub eax時執(zhí)行線程切換到另一個線程thread2中,此時ticketCount仍為99,執(zhí)行完3條匯編后ticketCount = 98,此時再切換回thread1,繼續(xù)執(zhí)行完后面匯編,也使ticketCount = 98,這里就導致同時輸出兩次98;

解決方法

保證某一線程ticketCount–沒做完,其他線程不允許做ticketCount–操作,可以使用加mutex互斥鎖的方法:

void sellTicket(int index)
{
	mtx.lock();
	while (ticketCount > 0)
	{
		//cout << "窗口:" << index << "賣出第:" << ticketCount << "張票" << endl;
		cout << ticketCount << endl; // 打印當前剩余票數(shù)
		ticketCount--;
		std::this_thread::sleep_for(std::chrono::milliseconds(10));
	}
	mtx.unlock();
}

但是這樣的加鎖問題在于鎖粒度太大,可以進一步縮小,采用鎖+雙重判斷的方法:

void sellTicket(int index)
{
	while (ticketCount > 0)
	{
		mtx.lock();
		if (ticketCount > 0) // !!!
		{
			cout << "窗口:" << index << "賣出第:" << ticketCount << "張票" << endl;
			//cout << ticketCount << endl; // 打印當前剩余票數(shù)
			ticketCount--;
		}
		mtx.unlock();
		std::this_thread::sleep_for(std::chrono::milliseconds(10));
	}
}

這里if (ticketCount > 0) 判斷必須加,如果不加,當ticketCount = 1時,切換到其他線程賣完后ticketCount = 0 ,切換回原線程繼續(xù)賣票就變成可以賣第0張票,不合法

lock_guard和unique_lock

lock_guard

lock_guard不能用在函數(shù)參數(shù)傳遞返回過程中,只能用在簡單的臨界區(qū)代碼段互斥操作;

類似于scoped_str;

lock_guard是對std::mutex的封裝,拷貝構造和賦值函數(shù)被delete,它是RAII技術的實踐,創(chuàng)建對象時就加鎖,出作用域析構調用解鎖,用lock_guard替換上面案例的mutex:

void sellTicket(int index)
{
	while (ticketCount > 0)
	{
		//mtx.lock();
		{
			lock_guard<std::mutex> lock(mtx); // 
			if (ticketCount > 0)
			{
				cout << "窗口:" << index << "賣出第:" << ticketCount << "張票" << endl;
				ticketCount--;
			}
		} 
		//mtx.unlock();
		std::this_thread::sleep_for(std::chrono::milliseconds(10));
	}
}

unique_lock

unique_lock不僅可用在函數(shù)參數(shù)傳遞或返回過程中,還能用在函數(shù)調用中,如 和條件變量函數(shù)一起使用:

unique_lock<std::mutex> lck(mtx);

cv.wait(lck); // => #1.使線程進入等待狀態(tài) #2.lck.unlock可以把mtx給釋放掉

unique_lock 也是對mutex的封裝,它也可以像lock_guard一樣使用,同時它支持手動調用lock unlock,會幫助檢查是否忘記調用unlock,使用例子如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-438224.html

void sellTicket(int index)
{
	while (ticketCount > 0)
	{
		{
			unique_lock<std::mutex> lck(mtx);
			lck.lock();
			if (ticketCount > 0)
			{
				cout << "窗口:" << index << "賣出第:" << ticketCount << "張票" << endl;
				ticketCount--;
			}
			lck.unlock();
		} 
		std::this_thread::sleep_for(std::chrono::milliseconds(10));
	}
}

到了這里,關于線程間互斥-mutex互斥鎖和lock_guard的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • C++11互斥量mutex使用詳解

    C++11互斥量mutex使用詳解

    mutex又稱互斥量,C++ 11中與 mutex相關的類(包括鎖類型)和函數(shù)都聲明在#include頭文件中,所以如果你需要使用 std::mutex,就必須包含#include頭文件。 C++11提供如下4種語義的互斥量(mutex) : std::mutex,獨占的互斥量,不能遞歸使用。 std::time_mutex,帶超時的獨占互斥量,不能遞

    2024年02月16日
    瀏覽(12)
  • 【Rust 基礎篇】Rust 互斥器(Mutex)

    在 Rust 中,互斥器(Mutex)是一種用于在多個線程之間共享數(shù)據(jù)的并發(fā)原語?;コ馄魈峁┝艘环N安全的方式,允許多個線程訪問共享數(shù)據(jù),但每次只允許一個線程進行寫操作。本篇博客將詳細介紹 Rust 中互斥器的使用方法,包含代碼示例和對定義的詳細解釋。 在 Rust 中,我們

    2024年02月15日
    瀏覽(16)
  • 互斥鎖、自旋鎖、讀寫鎖和文件鎖

    互斥鎖、自旋鎖、讀寫鎖和文件鎖

    互斥鎖(mutex)又叫互斥量,從本質上說是一把鎖,在訪問共享資源之前對互斥鎖進行上鎖,在訪問完成后釋放互斥鎖(解鎖);對互斥鎖進行上鎖之后,任何其它試圖再次對互斥鎖進行加鎖的線程都會被阻塞,直到當前線程釋放互斥鎖。如果釋放互斥鎖時有一個以上的線程

    2024年02月12日
    瀏覽(16)
  • 【Linux】線程互斥 -- 互斥鎖 | 死鎖 | 線程安全

    【Linux】線程互斥 -- 互斥鎖 | 死鎖 | 線程安全

    我們寫一個多線程同時訪問一個全局變量的情況(搶票系統(tǒng)),看看會出什么bug: 假如創(chuàng)建4個線程同時搶票,總票數(shù)有10000張,每個線程搶到票以后減一,按照正常情況我們應該是搶票到0截至。 多個線程交叉執(zhí)行本質:就是讓調度器盡可能的頻繁發(fā)生線程調度與切換 線程一般

    2024年02月14日
    瀏覽(90)
  • Java多線程:讀寫鎖和兩種同步方式的對比

    讀寫鎖ReentrantReadWriteLock概述 大型網(wǎng)站中很重要的一塊內容就是數(shù)據(jù)的讀寫,ReentrantLock雖然具有完全互斥排他的效果(即同一時間只有一個線程正在執(zhí)行l(wèi)ock后面的任務),但是效率非常低。所以在JDK中提供了一種讀寫鎖ReentrantReadWriteLock,使用它可以加快運行效率。 讀寫鎖表

    2023年04月09日
    瀏覽(21)
  • 多線程(線程互斥)

    多線程(線程互斥)

    學習了前面有關線程庫的操作后,我們就可以模擬搶票的過程 假設我們創(chuàng)建四個線程,分別代表我們的用戶 然后設定總票數(shù)為1000張,四個線程分別將進行循環(huán)搶票操作,其實就是循環(huán)對票數(shù)進行打印,并進行對應的減減操作 一旦票數(shù)為0,也就是票沒有了,我們就讓線程從

    2024年02月07日
    瀏覽(14)
  • 【探索Linux】—— 強大的命令行工具 P.20(多線程 | 線程互斥 | 互斥鎖 | 死鎖 | 資源饑餓)

    【探索Linux】—— 強大的命令行工具 P.20(多線程 | 線程互斥 | 互斥鎖 | 死鎖 | 資源饑餓)

    在上一篇文章中,我們對多線程編程的基礎知識進行了深入的探討,包括了線程的概念、線程控制以及分離線程等關鍵點。通過這些內容的學習,我們已經(jīng)能夠理解并實現(xiàn)簡單的多線程程序。然而,隨著程序復雜度的提升,僅僅掌握這些基礎是遠遠不夠的。在多線程環(huán)境下,

    2024年02月05日
    瀏覽(32)
  • Linux——線程3|線程互斥和同步

    Linux——線程3|線程互斥和同步

    我們上一篇提到過,多個線程執(zhí)行下面代碼可能會出錯,具體原因可查看上一篇Linux博客。 為避免這種錯誤的出現(xiàn),我們可采用加鎖保護。 PTHREAD_MUTEX_INITIALIZER 用pthread_mutex_t定義一把鎖。ptherad_mutex_init是對鎖進行初始化的函數(shù)。如果這把鎖是全局的并且是靜態(tài)定義的,我們可

    2024年02月05日
    瀏覽(28)
  • 【Linux】多線程2——線程互斥與同步/多線程應用

    【Linux】多線程2——線程互斥與同步/多線程應用

    ??上文主要介紹了多線程之間的獨立資源,本文將詳細介紹多線程之間的 共享資源 存在的問題和解決方法。 intro 多線程共享進程地址空間,包括創(chuàng)建的全局變量、堆、動態(tài)庫等。下面是基于全局變量實現(xiàn)的一個多線程搶票的demo。 發(fā)現(xiàn)錯誤:線程搶到負數(shù)編號的票,為什么

    2024年02月10日
    瀏覽(20)
  • 多線程基礎入門【Linux之旅】——上篇【線程控制,線程互斥,線程安全】

    多線程基礎入門【Linux之旅】——上篇【線程控制,線程互斥,線程安全】

    目錄 前文 回望頁表 一,什么是線程 二,使用 pthread_create (線程創(chuàng)建) 三,線程控制 1 ,線程共享進程數(shù)據(jù),但也擁有自己的一部分數(shù)據(jù): 2, 線程? VS 進程優(yōu)點 3,pthread_join(等待線程) 4,pthread_exit?(線程終止) 5, pthread_cancel (線程取消) 6. pthread_t 類型 7.? pthread_detac

    2024年01月16日
    瀏覽(93)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包