C++多線程實(shí)現(xiàn)綁定CPU的方法詳解

c++多線程實(shí)現(xiàn)綁定cpu的方法詳解

 

windows多線程

windows.h中提供了多線程解決方案,創(chuàng)建多線程的函數(shù)為

//返回值:一個(gè)handle類型的值,表示線程的句柄,可用于等待線程等函數(shù)
handle createthread(
lpsecurity_attributes   lpthreadattributes, // 不用管,一般為null
size_t                  dwstacksize,        // 堆棧大小,一般為0,表示默認(rèn)值
lpthread_start_routine  lpstartaddress,     // 函數(shù)指針
__drv_aliasesmem lpvoid lpparameter,        // 參數(shù)指針
dword                   dwcreationflags,    // 不用管,一般為0
lpdword                 lpthreadid          // 線程id,一般設(shè)為null
);

為了理解這個(gè)函數(shù),下面舉一個(gè)最簡(jiǎn)單的例子

#include<iostream>
#include<windows.h>

// 編寫了一個(gè)我的線程函數(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是一個(gè)用于創(chuàng)造新線程的函數(shù),其輸入?yún)?shù)ps是一個(gè)lpvoid類型的指針,在參數(shù)傳入后,將這個(gè)指針轉(zhuǎn)為整形指針(int *),然后將其賦給另一個(gè)整形指針n,然后在for循環(huán)中引用這個(gè)整形指針。

在main函數(shù)中,通過(guò)createthread函數(shù)創(chuàng)建一個(gè)線程并執(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
請(qǐng)按任意鍵繼續(xù). . .

 

windows調(diào)度與綁定cpu

作為成熟的操作系統(tǒng),windows為了更加充分利用cpu,會(huì)動(dòng)態(tài)分配線程占用的cpu資源,以確保每個(gè)cpu核心不過(guò)累;另一方面,intel作為成熟的cpu,為了充分考慮性能和能耗之間的均衡,當(dāng)cpu沒有滿負(fù)荷運(yùn)行的時(shí)候會(huì)自動(dòng)降頻。

這兩個(gè)合在一起就是,windows動(dòng)態(tài)分配cpu核心,讓每個(gè)cpu都不過(guò)載;然后intel動(dòng)態(tài)規(guī)劃能耗,讓每個(gè)核心都降頻。于是cpu的頻率越降越低,windows占用的資源越來(lái)越少,于是性能越來(lái)越差。

上面這個(gè)描述當(dāng)然略顯夸張了,但道理是這么個(gè)道理,為了驗(yàn)證這一點(diǎn),可以將上面的mythread函數(shù)稍作改動(dòng),

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í)行線程時(shí)所使用的cpu,發(fā)現(xiàn)每次運(yùn)行時(shí)使用的cpu是隨機(jī)的。

通過(guò)windows.h中的setthreadaffinitymask來(lái)手動(dòng)分配cpu,使用方法非常簡(jiǎn)單

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
請(qǐng)按任意鍵繼續(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++多線程實(shí)現(xiàn)綁定cpu的方法詳解的文章就介紹至此,更多相關(guān)c++多線程綁定cpu內(nèi)容請(qǐng)搜索碩編程以前的文章,希望以后支持碩編程!

下一節(jié):c++?折疊參數(shù)包詳解(悄然增強(qiáng)編程效率)

c語(yǔ)言編程技術(shù)

相關(guān)文章
亚洲国产精品第一区二区,久久免费视频77,99V久久综合狠狠综合久久,国产免费久久九九免费视频