我刚开始用“ Win32中的多线程应用程序-Jim BEVERIDGE,Robert WIENER”一书学习多线程。这本书来自1997年。
从第50页开始,其中有一个忙等待部分,一个目标是表明创建第二个线程并在主线程中等待第二个线程完成会浪费大量时间。有一个示例C程序演示了这一点,首先,对在主线程中调用的函数进行计时,然后在主线程等待时创建线程并在那里进行工作。这是程序。
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
DWORD WINAPI SomeWork(LPVOID);
int main(int argc, char *argv[])
{
HANDLE hThrd;
DWORD exitCode = 0;
DWORD threadId;
DWORD begin;
DWORD elapsed;
// PART 1: doing the work in the main thread
puts("Timing normal function call...");
begin = GetTickCount();
SomeWork(0);
elapsed = GetTickCount() - begin;
printf("Function call took: %d.%.03d seconds\n\n", elapsed / 1000, elapsed % 1000);
// Result:
// ===> 1.391 seconds <===
// PART 2: doing the work in a second thread
puts("Timing thread + busy loop...");
begin = GetTickCount();
hThrd = CreateThread(NULL,
0,
SomeWork,
(LPVOID)1,
0,
&threadId);
// This busy loop (should) chews up a lot of CPU time
while( 1 ) {
GetExitCodeThread(hThrd, &exitCode);
if( exitCode != STILL_ACTIVE ) {
break;
}
}
elapsed = GetTickCount() - begin;
printf("Thread + busy loop took: %d.%.03d seconds\n\n", elapsed / 1000, elapsed % 1000);
// Result:
// ===> 1.375 seconds <==
CloseHandle(hThrd);
printf("Press a key to quit...");
getchar();
return EXIT_SUCCESS;
}
// Routine that uses probability to approximate PI.
DWORD WINAPI SomeWork(LPVOID n)
{
int i;
int inside = 0;
double val;
srand( (unsigned) time(NULL) );
int TIMES = 10000000;
for(i=0; i < TIMES; ++i) {
double x = (double) (rand())/RAND_MAX;
double y = (double) (rand())/RAND_MAX;
if( (x*x+y*y) <= 1.0 ) {
++inside;
}
}
val = (double)inside / TIMES;
printf("PI = %.4g\n", val*4);
return 0;
}
在书中,作者写下了他们得到的时间:
在主线程中调用的函数:7.993秒。
在另一个线程+繁忙循环中调用的函数:15.946秒。
但是,这是我的措施:
在主线程中调用的函数:1.391秒。
在另一个线程+繁忙循环中调用的函数:1.375秒。
我多次运行它,两次大致相同。所以我的问题是为什么它们相同?繁忙的循环难道不应该吃很多时间吗?由于我的计算机具有四个内核,也许Windows将两个线程放在了不同的内核上?