windows - Windows 中的进程创建开销是多少?

标签 windows process

我一直听说在 Windows 中创建新进程的成本非常高。但我找不到确切的数字。有大概的循环次数吗? 2GHz 双核处理器上有多少毫秒?

我用 Python 编写了一个测试程序并测量了每个进程 5 毫秒,但我不知道其中有多少是 Python 的额外开销。我猜不会太多。

最佳答案

有趣的问题!

如前所述,开销很高。出于好奇,是否快速编写了一个小的基准测试来了解线程和进程的创建需要多长时间以及这些时间之间的关系。

#include <windows.h>
#include <stdio.h>
#include <conio.h>

#define MIN   0
#define AVG   1
#define MAX   2

DWORD WINAPI thread(LPVOID lpvData)
{
    return (0);
}

int main()
{
    BOOL result;
    int iteration;
    int i;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    DWORD tStart;
    DWORD tEllapsed;
    double tCall;
    int spawnCount;
    HANDLE hThread;
    DWORD threadId;
    double ratio;
    double statCreateProcess[3];
    double statCreateThread[3];


    for (iteration = 0; iteration < 16; iteration++)
    {
        /*
        **  Measure creation time of process
        */
        tEllapsed = 0;
        spawnCount = 0;
        for (i = 0; i < 100; i++)
        {
            ZeroMemory(&si, sizeof(si));
            si.cb = sizeof(si);
            ZeroMemory(&pi, sizeof(pi));

            tStart = GetTickCount();
            result = CreateProcess(NULL,
                                   "cmd.exe",
                                   NULL,
                                   NULL,
                                   FALSE,
                                   NORMAL_PRIORITY_CLASS,
                                   NULL,
                                   NULL,
                                   &si,
                                   &pi);

            if (result != FALSE)
            {
                tEllapsed += GetTickCount() - tStart;
                spawnCount++;

                // clean up...
                TerminateProcess(pi.hProcess, 0);
                CloseHandle(pi.hThread);
                CloseHandle(pi.hProcess);
            }
        }
        tCall = tEllapsed / (double)spawnCount;
        printf("average creation time of process: %0.3fms\n", tCall);

        // track statistics...
        if (iteration > 0)
        {
            if (statCreateProcess[MIN] > tCall)
                statCreateProcess[MIN] = tCall;
            statCreateProcess[AVG] += tCall;
            if (statCreateProcess[MAX] < tCall)
                statCreateProcess[MAX] = tCall;
        }
        else
        {
            statCreateProcess[MIN] = tCall;
            statCreateProcess[AVG] = tCall;
            statCreateProcess[MAX] = tCall;
        }


        /* measure creation time of thread */
        spawnCount = 0;
        tStart = GetTickCount();
        for (i = 0; i < 5000; i++)
        {           
            hThread = CreateThread(NULL,
                                   0,
                                   thread,
                                   NULL,
                                   0,
                                   &threadId);
            if (hThread != NULL)
            {
                spawnCount++;

                // clean up...
                CloseHandle(hThread);
            }
        }
        tEllapsed = GetTickCount() - tStart;
        tCall = tEllapsed / (double)spawnCount;
        printf("average creation time of thread: %0.3fms\n", tCall);

        // track statistics...
        if (iteration > 0)
        {
            if (statCreateThread[MIN] > tCall)
                statCreateThread[MIN] = tCall;
            statCreateThread[AVG] += tCall;
            if (statCreateThread[MAX] < tCall)
                statCreateThread[MAX] = tCall;
        }
        else
        {
            statCreateThread[MIN] = tCall;
            statCreateThread[AVG] = tCall;
            statCreateThread[MAX] = tCall;
        }
    } /* for (iteration = ...) */

    statCreateProcess[AVG] /= iteration;
    statCreateThread[AVG] /= iteration;

    printf("\n\n--- CreateProcess(..) ---\n");
    printf("minimum execution time ...: %0.3fms\n", statCreateProcess[MIN]);
    printf("average execution time ...: %0.3fms\n", statCreateProcess[AVG]);
    printf("maximum execution time ...: %0.3fms\n", statCreateProcess[MAX]);
    printf("\n--- CreateThread(..) ---\n");
    printf("minimum execution time ...: %0.3fms\n", statCreateThread[MIN]);
    printf("average execution time ...: %0.3fms\n", statCreateThread[AVG]);
    printf("maximum execution time ...: %0.3fms\n", statCreateThread[MAX]);

    ratio = statCreateProcess[AVG] / statCreateThread[AVG];
    printf("\n\nratio: %0.3f\n\n", ratio);

    getch();
    return (0);
}

我已经在我的计算机(i5 3.2GHz;Windows 7)上运行了几次,如果关闭防病毒应用程序并且从 Visual Studio 外部启动基准测试,则这些值非常一致:

--- CreateProcess(..) ---
minimum execution time ...: 11.860ms
average execution time ...: 12.756ms
maximum execution time ...: 14.980ms

--- CreateThread(..) ---
minimum execution time ...: 0.034ms
average execution time ...: 0.037ms
maximum execution time ...: 0.044ms


ratio: 342.565

正如预期的那样,CreateProcess(..) 的变化更大,因为涉及更多的系统调用并且被另一个线程中断的可能性更高。请记住,创建线程的时间甚至更短,因为时间测量包括整个控制循环(否则 GetTickCount(..) 测量时间会太不准确)。

在运行 Windows XP 的虚拟 PC 上进行的另一项测试(在与上述相同的机器上运行)产生了以下值:

--- CreateProcess(..) ---
minimum execution time ...: 22.630ms
average execution time ...: 24.666ms
maximum execution time ...: 27.340ms

--- CreateThread(..) ---
minimum execution time ...: 0.076ms
average execution time ...: 0.086ms
maximum execution time ...: 0.100ms


ratio: 287.982

有趣的是,CreateProcess(..) 和 CreateThread(..) 的平均执行时间之比非常接近。

看到其他机器和 Windows 版本的值会很有趣。如果大约 300 的比率在不同的计算机和 Windows 版本上大致相同,我不会感到惊讶。

那么让我们得出结论:CreateProcess(..) 在 Windows 上比 CreateThread(..) 慢很多。但实际上我很震惊它到底有多慢...

关于windows - Windows 中的进程创建开销是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10710912/

相关文章:

Java 生成新的 cmd.exe 并获取输出流

Linux、waitpid、WNOHANG、子进程、僵尸

c# - 如何在系统启动时自动运行应用程序?

windows - 如何在 nodejs 中发送 CONTROL+C

windows - 如何在法语本地化 Windows 上获取英语用户名?

c - 如何将一个进程的标准输出重定向到另一个进程的标准输入?

java - 无法从 Runtime.getRunTime.exec() 获取 getInputStream

windows - 批处理脚本中没有扩展名的文件名

Android 应用程序与。过程

c - XV6-循环调度程序