0

我有一系列 Win64 控制台应用程序,一个是“主”,另外 16 个是“从”。

这个逻辑的原始版本只有一个可执行文件,当使用命令行参数“init”启动时,它会初始化一个非常大的数据集(3gigs),然后坐在 Windows 消息泵上等待请求分析该大数据集的消息. 当需要对数据集进行分析时,启动同一个可执行文件并带有分析请求参数,新启动的可执行文件会找到自己已经初始化的实例的窗口句柄,并将分析请求和参数发送到已经初始化的实例通过Windows 消息 WM_COPYDATA。这就像一个单一的可执行架构的魅力。

但是,现在我有一个更强大的系统,我想同时运行多个分析可执行文件,每个都在不同的内核上。因此,我创建了一个新架构,其中有 16 个分析可执行文件充当充当“主”的管理器控制台应用程序的“从属”。(仅供参考,一个分析请求可能需要 0.5 到 4.0 秒 - 因此我希望一次运行多个。)

仍然使用 Windows 消息作为我的通信方式,使用 SendMessage() 会阻止调用者,直到消息被接收者处理。这不好,因为我希望同时处理这些消息。因此,我尝试使用异步 Windows 消息函数,例如 SendMessageCallback() 和 SendNotifyMessage()。它们要么失败,要么以阻塞方式执行,而不是同时执行。

更多的研究使我将“命名共享内存”作为我的可执行文件(本质上是内存映射文件)之间通信的一种方式。所以我设置了它,我的主人现在能够创建命名共享内存块,我所有的可执行文件都能够请求相同内存的视图,并且通过状态机处理命名共享内存中的数据,我主从之间有同步。

但是,我发现主人和奴隶似乎没有连续运行。

我仍在使用 master 的基本思想是通过保存分析参数的命令行启动的,该可执行文件使用命名共享内存设置以及所有从属的当前状态向已经运行的版本发送一条消息,然后一个可用的从机被选中,它的命名共享内存驻留状态机获取分析请求。

这部分工作正常。但是,从属设备似乎处于睡眠或其他休眠状态,因为我修改后的 Windows 消息循环似乎没有循环。

这是我当前的 Windows 消息处理循环的样子:

while (1) {
    int status = ::GetMessage(&msg, 0, 0, 0);
    if (status != 0) {
        if (status == -1) return -1
        ::DispatchMessage(&msg);
    } 
    else if (status == 0)
        break;
    HandleSharedMemoryDeliveredTasks(); // NOTE: checking Named Shared Memory
}

除非收到 Windows 消息,否则不会触发在此循环内放置断点。

所以,我想知道如何让我的循环保持活动状态,以便继续检查命名共享内存而不必发送(阻塞)消息。

我知道我正在一个问题空间中操作,我应该将我的主从可执行文件转换为 Windows 服务。但是,我非常非常接近让这个工作(似乎),并且重写到 Windows 服务是我没有经验的领域。

此外,我在我的可执行文件中使用它来保持它们处于活动状态(但它似乎没有帮助):

// during program init:
SetThreadExecutationState(ES_CONTINIOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED);

有什么建议可以在主设备设置状态机进行工作时异步“唤醒”从设备,并且在工作完成时让从设备“唤醒”主设备?

4

0 回答 0