在windows / c ++上使用多进程应用程序进行高精度定时操作

问题描述 投票:-4回答:2

我的主程序创建了多个进程(由子项目生成的不同exe文件)。

我想要做的是在每40-50毫秒主框架内运行每个进程约1-2毫秒。当我使用挂起/恢复线程暂停一个进程(通过挂起它拥有的所有线程,但每个只有一个。)并继续下一步时,只有一个交换机上下文(暂挂旧和恢复新)持续大约60毫秒。甚至我的主要框架也更长。顺便说一下,我知道不建议以这种方式使用睡眠,因为唯一的睡眠/唤醒操作持续15-30毫秒,我不使用任何。

如果我将正在运行的进程的优先级更改为更低,则将下一个进程更改为更高;是否保证在微秒内由窗口发生上下文切换?或者我应该考虑什么来实现一个只有微秒敏感的过程开关?我想知道简单的Suspend / ResumeThread操作通常需要多长时间?

目前我不能使用进程的线程,因为我需要进程的内存隔离,我的进程可能会产生并终止自己的线程。 Waithandlers喜欢同步方法会给我很高的精确时间吗?

编辑:建议的同步对象的分辨率最大为毫秒(如等待定时器,多媒体定时器等所有获取参数为ms并给出ms)。我需要使用QueryPerformanceCounter和其他方法来实现高分辨率。

c++ winapi
2个回答
1
投票

正如雷米所说,你应该用同步对象做这件事 - 这就是他们的目的。让我们假设进程A首先执行,并希望在某个时刻“移交”进程B.然后它可以这样做:

SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE };
HANDLE hHandOffToA = CreateEventW (&sa, TRUE, FALSE, L"HandOffToA");
HANDLE hHandOffToB = CreateEventW (&sa, TRUE, FALSE, L"HandOffToB");

// Start process B
CreateProcess (...);

while (!quit)
{
    // Do work, and then:
    SetEvent (hHandOffToB);
    WaitForSingleObject (hHandOffToA, INFINITE);
}

CloseHandle (hHandOffToA);
CloseHandle (hHandOffToB);

然后进程B可以执行:

HANDLE hHandOffToA = OpenEventW (EVENT_MODIFY_STATE, FALSE, L"HandoffToA");
HANDLE hHandOffToB = OpenEventW (SYNCHRONIZE, FALSE, L"HandoffToB");

while (!quit)    
{
    WaitForSingleObject (hHandOffToB, INFINITE);
    // Do work, and then:
    SetEvent (hHandOffToA);
}

CloseHandle (hHandOffToA);
CloseHandle (hHandOffToB);

当然,您应该包括正确的错误检查,我已经让您决定进程A应该如何告诉进程B关闭(我猜它可能会杀死它)。还要记住,事件名称是系统范围的,因此请比我更仔细地选择它们。


0
投票

对于非常高的精度,可以使用以下功能:

void get_clock(LONGLONG* SYSTEM_TIME)
{
    static REAL64 multiplier = 1.0;
    static BOOL alreadyCalculated = FALSE;

    if (alreadyCalculated == FALSE)
    {
        LARGE_INTEGER frequency;
        BOOL result = QueryPerformanceFrequency(&frequency);
        if (result == TRUE)
        {
            multiplier = 1000000000.0 / frequency.QuadPart;
        }
        else
        {
            DWORD error = GetLastError();
        }
        alreadyCalculated = TRUE;
   }

    LARGE_INTEGER time;
    QueryPerformanceCounter(&time);

    *SYSTEM_TIME = static_cast<SYSTEM_TIME_TYPE>(time.QuadPart * multiplier);
}

在我的情况下,同步对象不太适合(但是我已经在时间不重要的地方使用它们),而是我重新设计了我的逻辑以将我的线程需要采取行动的地方持有者放置并使用上面的函数计算时间。

但仍然不确定更高优先级的任务是否到达需要多长时间才能将Windows带入CPU并抢占运行它。

© www.soinside.com 2019 - 2024. All rights reserved.