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

jap*_*iss 12 windows process

我一直听说在Windows中创建新进程非常昂贵.但我找不到确切的数字.是否有一个球场周期数?2GHz双核处理器上多少毫秒?

我用Python编写了一个测试程序,每个进程测量5ms,但我不知道有多少是Python的额外开销.我猜不多.

Luk*_*sen 24

有趣的问题!

如前所述,开销很高.出于好奇,如果已经快速编写了一些基准,以获得一个线程和一个过程的创建需要多长时间以及这些时间如何相关.

#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);
}
Run Code Online (Sandbox Code Playgroud)

我已经在我的计算机上运行了几次(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
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,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
Run Code Online (Sandbox Code Playgroud)

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

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

因此,让我们得出结论:CreateProcess的(..)是 比在Windows的CreateThread(..)慢.但实际上我真的很震惊它实际上是多么慢......

  • @IInspectable 好吧,试试吧。我猜磁盘 I/O 开销并没有那么多,因为在我重试期间可执行文件已经位于磁盘缓存中。如果结果没有那么大的不同,我不会感到惊讶。正如您所看到的,我在我的电脑和虚拟电脑上对此进行了测试,比率非常接近......让我知道您的结果。 (2认同)