所以我创建了以下简单程序来测量在我的机器上创建进程或线程的平均时间:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
DWORD WINAPI ThreadFunc(void* data) {
return 0;
}
int main(int argc, char** argv) {
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
clock_t begin, end;
double cpu_time_used;
for(int i = 0; i <= 1000000;i++){
begin = clock();
CreateProcess(NULL, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
end = clock();
cpu_time_used += ((double) (end - begin)) / CLOCKS_PER_SEC;
TerminateProcess(pi.hProcess, 0);
}
/* since we're running 1 000 000 (1 million) times we divide by 1
* million and since to get the time in ns instead of ns we multiply by
* 1 billion we simply multiply by 1000 since 1 billion / 1 million = 1000.
*/
printf("Average time to create a process = %f ns\n", cpu_time_used * 1000);
cpu_time_used = 0;
for(int i = 0; i < 1000000;i++){
begin = clock();
CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
end = clock();
cpu_time_used += ((double) (end - begin)) / CLOCKS_PER_SEC;
}
/* since we're running 1 000 000 (1 million) times we divide by 1
* million and since to get the time in ns instead of ns we multiply by
* 1 billion we simply multiply by 1000 since 1 billion / 1 million = 1000.
*/
printf("Average time to create a Thread = %f ns\n", cpu_time_used * 1000);
return (EXIT_SUCCESS);
}
结果如下:
Average time to create a process = 89.000000 ns
Average time to create a Thread = 112055.000000 ns
创建一个进程的时间看起来很合理,但为什么创建一个线程比创建一个全新的进程要多一千倍呢?
最佳答案
好的,我的方法有几个错误,我将在这里解释,并在最后给出完整的最终代码。
- CreateProcess() 调用什么都不做,而不是启动一个什么也不做的程序。
要解决此问题,我们将
CreateProcess(NULL, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
更改为CreateProcess("C:\\Windows\\System32\\rundll32.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
为了更好的衡量,我们暂停了进程。 - Windows 将程序限制为 2048 个线程。这意味着在第 2048 个线程之后出现了额外的瓶颈,因为程序会等待线程关闭以打开一个新线程。为了避免这种情况,我将循环次数减少到只有 1000 次。
- clock() 对于多线程程序来说是不准确的,正如@Some programmer dude 所指出的,相反,我们使用 QueryPerformanceCounter()。请记住,根据您的 IDE 和其他因素,QueryPerformanceFrequency 可能会错误地返回 10 MHz(NetBeans 有这个问题,因此更改为 Visual Studio),因此请先对其进行测试。
固定的最终代码是:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
DWORD WINAPI ThreadFunc(void* data) {
return 0;
}
int main(int argc, char** argv) {
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
LARGE_INTEGER begin, end, cpu_time_used;
LARGE_INTEGER Frequency;
cpu_time_used.QuadPart = 0;
QueryPerformanceFrequency(&Frequency);
for (int i = 0; i <= 1000; i++) {
QueryPerformanceCounter(&begin);
CreateProcess("C:\\Windows\\System32\\rundll32.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
QueryPerformanceCounter(&end);
cpu_time_used.QuadPart += end.QuadPart - begin.QuadPart;
TerminateProcess(pi.hProcess, 0);
}
cpu_time_used.QuadPart *= 1000000;
cpu_time_used.QuadPart /= Frequency.QuadPart;
printf("Average time to create a process = %lld us\n", cpu_time_used.QuadPart / 1000);
cpu_time_used.QuadPart = 0;
HANDLE hThread;
for (int i = 0; i <= 1000; i++) {
QueryPerformanceCounter(&begin);
hThread = CreateThread(NULL, 0, ThreadFunc, NULL, CREATE_SUSPENDED, NULL);
QueryPerformanceCounter(&end);
cpu_time_used.QuadPart += end.QuadPart - begin.QuadPart;
}
cpu_time_used.QuadPart *= 1000000;
cpu_time_used.QuadPart /= Frequency.QuadPart;
printf("Average time to create a Thread = %lld us\n", cpu_time_used.QuadPart / 1000);
return (EXIT_SUCCESS);
}
返回:
Average time to create a process = 8289 us
Average time to create a Thread = 26 us
关于c - 使用 CreateThread() 时在 Windows 中获取线程创建的荒谬时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58570454/