C++ windows/c环境下多进程应用的高精度定时操作++

C++ windows/c环境下多进程应用的高精度定时操作++,c++,winapi,C++,Winapi,我有多个进程,它们位于由主程序创建的子项目生成的不同exe文件中 我想做的是在每40-50毫秒的主帧内运行每个进程大约1-2毫秒。当我使用suspend/resume thread挂起一个进程时,挂起它拥有的所有线程,但每个线程只有一个。接下来继续,只有一个开关contextsuspend old和resume new持续约60毫秒。它甚至比我的主框架还要长。顺便说一句,我知道在这种情况下不建议使用睡眠,因为唯一的睡眠/唤醒操作持续15-30毫秒,我不使用任何 如果我将正在运行的进程的优先级更改

我有多个进程,它们位于由主程序创建的子项目生成的不同exe文件中

我想做的是在每40-50毫秒的主帧内运行每个进程大约1-2毫秒。当我使用suspend/resume thread挂起一个进程时,挂起它拥有的所有线程,但每个线程只有一个。接下来继续,只有一个开关contextsuspend old和resume new持续约60毫秒。它甚至比我的主框架还要长。顺便说一句,我知道在这种情况下不建议使用睡眠,因为唯一的睡眠/唤醒操作持续15-30毫秒,我不使用任何

如果我将正在运行的进程的优先级更改为较低,将下一个进程的优先级更改为较高;windows是否保证在微秒内进行上下文切换? 或者我应该怎么做才能实现一个微秒级敏感的过程开关? 我想知道一个简单的挂起/恢复线程操作通常需要多长时间

目前我不能用线程代替进程,因为我需要进程的内存隔离,我的进程可能会产生并终止它们自己的线程。像同步方法这样的WaitHandler是否给了我高精度的时间


编辑:建议的同步对象集的分辨率最大为毫秒,如可等待计时器、多媒体计时器等。所有参数均以毫秒为单位获取,并为您提供毫秒。如我所述,我需要使用QueryPerformanceCounter和其他方法来实现高分辨率。

如Remy所说,您应该对同步对象执行此操作-这就是它们的用途。让我们假设进程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关闭,我想它可能会杀死它。还请记住,事件名称是系统范围的,因此选择它们要比我做的更仔细。

要获得非常高的精度,可以使用以下函数:

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);
}
在我的例子中,sync对象不太适合,但是我在时间不重要的地方使用了它们,相反,我重新设计了逻辑,在线程需要执行操作的地方放置了占位符,并使用上面的函数计算了时间


但仍不确定高优先级任务是否到达windows需要多长时间才能进入cpu并抢先运行一个任务。

试图将您的意愿强加给外部进程不太可能奏效。合作更有可能是有效的。也就是说,你所描述的听起来不像是任何问题的解决方案。为什么你要使用多个子进程,而不是简单地在一个进程中使用多个线程?在任何情况下,支持/恢复线程都是非常糟糕的设计。改为使用,例如,等等。我需要进程,因为它们的性质是线程不起作用的,拥有受保护的内存空间等。就高精度时间部分而言,可能会引起兴趣。不过,正如您所发现的,进程同步非常重。因此,也许你应该重新考虑设计,因为它听起来并不像是解决任何问题的方法。这种方法的问题是,我想做的上下文切换只在主进程中完成,并且只在指定的时间完成时完成,而不管子进程是否完成了它们的工作。是的,rtos逻辑。不过,我会尝试让它适合我的方法。好吧,不管你想要什么逻辑,在调度方面,这是正确的基本方法——即让每个依赖进程等待一个可等待的对象,直到它被要求做某事。睡觉或纺纱都不是办法。好吧,我得到了。摆在我面前的问题是msdn指定“句柄必须具有同步访问权限。有关更多信息,请参阅标准访问权限。”在代码中,我应该指定此标志。我在谷歌上找不到这个?我想我在我的例子中已经提到了。我错过什么了吗?需要同步访问来等待句柄,并且在调用OpenEvent时指定该句柄。据我所知,这就是你需要做的。WaitableTimers和对象需要一个以毫秒为单位的参数,对我来说分辨率非常低。