C++多線程實現(xiàn)綁定CPU的方法詳解
Windows多線程
windows.h中提供了多線程解決方案,創(chuàng)建多線程的函數(shù)為
//返回值:一個HANDLE類型的值,表示線程的句柄,可用于等待線程等函數(shù) HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // 不用管,一般為NULL SIZE_T dwStackSize, // 堆棧大小,一般為0,表示默認值 LPTHREAD_START_ROUTINE lpStartAddress, // 函數(shù)指針 __drv_aliasesMem LPVOID lpParameter, // 參數(shù)指針 DWORD dwCreationFlags, // 不用管,一般為0 LPDWORD lpThreadId // 線程id,一般設(shè)為NULL );
為了理解這個函數(shù),下面舉一個最簡單的例子
#include<iostream> #include<windows.h> // 編寫了一個我的線程函數(shù) DWORD WINAPI MyThread(LPVOID ps) { int *n = (int *)ps; for (int i = 0; i < 3; ++i) printf("執(zhí)行線程%d, i=%d\n", n[0], i); return 0L; } int main() { // 創(chuàng)造線程 int id1 = 1, id2=2; CreateThread(NULL, 0, MyThread, &id1, 0, NULL); CreateThread(NULL, 0, MyThread, &id2, 0, NULL); system("PAUSE"); return 0; }
其中,MyThread是一個用于創(chuàng)造新線程的函數(shù),其輸入?yún)?shù)ps是一個LPVOID類型的指針,在參數(shù)傳入后,將這個指針轉(zhuǎn)為整形指針(int *),然后將其賦給另一個整形指針n,然后在for循環(huán)中引用這個整形指針。
在main函數(shù)中,通過CreateThread函數(shù)創(chuàng)建一個線程并執(zhí)行,其中執(zhí)行的函數(shù)為MyThread,傳入的參數(shù)為id1, id2的地址。執(zhí)行后的結(jié)果為
執(zhí)行線程2, i=0
執(zhí)行線程1, i=0
執(zhí)行線程1, i=1
執(zhí)行線程1, i=2
執(zhí)行線程2, i=1
執(zhí)行線程2, i=2
請按任意鍵繼續(xù). . .
windows調(diào)度與綁定CPU
作為成熟的操作系統(tǒng),Windows為了更加充分利用CPU,會動態(tài)分配線程占用的CPU資源,以確保每個CPU核心不過累;另一方面,Intel作為成熟的CPU,為了充分考慮性能和能耗之間的均衡,當CPU沒有滿負荷運行的時候會自動降頻。
這兩個合在一起就是,Windows動態(tài)分配CPU核心,讓每個CPU都不過載;然后Intel動態(tài)規(guī)劃能耗,讓每個核心都降頻。于是CPU的頻率越降越低,Windows占用的資源越來越少,于是性能越來越差。
上面這個描述當然略顯夸張了,但道理是這么個道理,為了驗證這一點,可以將上面的MyThread函數(shù)稍作改動,
DWORD WINAPI MyThread(LPVOID ps) { int* n = (int*)ps; int cpu = GetCurrentProcessorNumber(); for (int i = 0; i < 5; ++i) { printf("在CPU%d上執(zhí)行線程%d, i=%d\n", cpu, n[0], i); Sleep(100); } return 0L; }
這樣就可以查看每次執(zhí)行線程時所使用的CPU,發(fā)現(xiàn)每次運行時使用的CPU是隨機的。
通過windows.h中的SetThreadAffinityMask來手動分配CPU,使用方法非常簡單
int main() { // 創(chuàng)造線程 int id1 = 1, id2=2; auto th1 = CreateThread(NULL, 0, MyThread, &id1, 0, NULL); SetThreadAffinityMask(th1, 0x01); auto th2 = CreateThread(NULL, 0, MyThread, &id2, 0, NULL); SetThreadAffinityMask(th2, 0x02); // 記得等待線程結(jié)束 system("PAUSE"); return 0; }
效果如下
在CPU0上執(zhí)行線程1, i=0
在CPU1上執(zhí)行線程2, i=0
請按任意鍵繼續(xù). . . 在CPU1上執(zhí)行線程2, i=1
在CPU0上執(zhí)行線程1, i=1
在CPU0上執(zhí)行線程1, i=2
在CPU1上執(zhí)行線程2, i=2
在CPU1上執(zhí)行線程2, i=3
在CPU0上執(zhí)行線程1, i=3
在CPU1上執(zhí)行線程2, i=4
在CPU0上執(zhí)行線程1, i=4
到此這篇關(guān)于C++多線程實現(xiàn)綁定CPU的方法詳解的文章就介紹到這了,更多相關(guān)C++多線程綁定CPU內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++ const的使用及this指針常方法(面試最愛問的this指針)
這篇文章主要介紹了C++ const的使用,this指針,常方法(面試最愛問的this指針),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04C/C++實現(xiàn)個人收支系統(tǒng)的示例代碼
這篇文章主要介紹了C/C++實現(xiàn)個人收支系統(tǒng),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06關(guān)于C++靜態(tài)成員函數(shù)訪問非靜態(tài)成員變量的問題
靜態(tài)成員函數(shù)不能訪問非靜態(tài)成員,這是因為靜態(tài)函數(shù)屬于類而不是屬于整個對象,靜態(tài)函數(shù)中的 member可能都沒有分配內(nèi)存。靜態(tài)成員函數(shù)沒有隱含的this自變量。所以,它就無法訪問自己類的非靜態(tài)成員2013-10-10C語言中的自定義類型之結(jié)構(gòu)體與枚舉和聯(lián)合詳解
今天我們來學習一下自定義類型,自定義類型包括結(jié)構(gòu)體、枚舉、聯(lián)合體,小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考2022-06-06