我正在寻找一种跨平台方法来通知多个客户端应用程序服务/守护程序已启动并且能够处理传入连接。客户端将一直运行,而服务可能不会。通常,服务/守护程序将在计算机启动时自动启动,但在某些情况下可能不会,在这种情况下,客户端应该在服务/守护程序启动时自动连接。
客户端的基本流程是等到他们注意到服务正在运行,然后连接。如果连接中断或他们无法连接,他们只需从头开始重试。
对于 Windows,我有一个解决方案,其中服务在启动时会发出一个全局事件对象的信号,以便客户端可以等待此事件。这在现实中可以正常工作,但我很确定它不能处理所有潜在的情况(例如崩溃的服务或正在运行的服务的多个实例)。我不介意客户是否“不小心”时不时地醒来,即使服务没有运行。我只是想避免客户端进入一个繁忙的循环,试图一直连接,同时对服务启动做出快速响应。即只是在连接尝试之间添加一个睡眠并不是很好。
是否有跨平台方法来检测服务是否正在运行并准备好接受连接?
更新:我将使用内存中的近似代码添加更多关于当前机制如何在 Windows 上工作的信息,因此请原谅任何拼写错误:
服务:
SECURITY_ATTRIBUTES sa;
// Set up empty SECURITY_ATTRIBUTES so that everyone has access
// ...
// Create a manual reset event, initially set to nonsignaled
HANDLE event = ::CreateEvent(&sa, TRUE, FALSE, "Global\\unique_name");
// Signal the event - service is running and ready
::SetEvent(event);
// Handle connections, do work
// If the service dies for whatever reason, Windows deletes the event handle
// The event is deleted when the last open handle to it is closed
// So the event is signaled for at least as long as the service lives
客户:
while (true) {
// Set up event the same way as the service, including empty security attributes
// ...
HANDLE event = ::CreateEvent(&sa, TRUE, FALSE, "Global\\unique_name");
// Wait for the service to start
DWORD ret = ::WaitForSingleObject(event, INFINITE);
// Close the handle to avoid keeping the event object alive
// This isn´t enough in theory, but works in real usage as the number of clients
// will always be low
::CloseHandle(event);
// Check if we woke up because the event is signaled
if (WAIT_OBJECT_0 == ret) {
// connect to service, do work
// ...
}
}
我怎样才能在 OS X 和 Linux 上实现大致相同的效果?