什么是WaitNamedPipe的重叠I/O替代品? [英] What is an overlapped I/O alternative to WaitNamedPipe?
问题描述
WaitNamedPipe
函数允许管道客户端应用程序同步等待命名管道服务器上的可用连接.然后,您呼叫 CreateFile
打开作为客户的管道.伪代码:
The WaitNamedPipe
function allows a pipe client application to synchronously wait for an available connection on a named pipe server. You then call CreateFile
to open the pipe as a client. Pseudocode:
// loop works around race condition with WaitNamedPipe and CreateFile
HANDLE hPipe;
while (true) {
if (WaitNamedPipe says connection is ready) {
hPipe = CreateFile(...);
if (hPipe ok or last error is NOT pipe busy) {
break; // hPipe is valid or last error is set
}
} else {
break; // WaitNamedPipe failed
}
}
问题在于这些都是阻塞的同步调用.异步执行此操作的好方法是什么?例如,我似乎找不到使用重叠I/O的API.例如,对于管道服务器, WaitForMultipleObjects 和等待I/O操作完成,或等待任何其他事件发出信号(例如,一个事件通知线程取消挂起的I/O并终止).
The problem is that these are all blocking, synchronous calls. What is a good way to do this asynchronously? I can't seem to find an API that uses overlapped I/O to do this, for example. For example, for pipe servers the ConnectNamedPipe
function provides an lpOverlapped
parameters allowing for a server to asynchronously wait for a client. The pipe server can then call WaitForMultipleObjects and wait for the I/O operation to complete, or any other event to be signaled (for example, an event signaling the thread to cancel pending I/O and terminate).
我能想到的唯一方法是在一个短而有限的超时循环中调用WaitNamedPipe
,并检查其他信号是否超时.或者,在循环调用CreateFile
中,检查其他信号,然后在短暂延迟(或WaitNamedPipe
)中调用Sleep
.例如:
The only way I can think of is to call WaitNamedPipe
in a loop with a short, finite timeout and check other signals if it times out. Alternatively, in a loop call CreateFile
, check other signals, and then call Sleep
with a short delay (or WaitNamedPipe
). For example:
HANDLE hPipe;
while (true) {
hPipe = CreateFile(...);
if (hPipe not valid and pipe is busy) {
// sleep 100 milliseconds; alternatively, call WaitNamedPipe with timeout
Sleep(100);
// TODO: check other signals here to see if we should abort I/O
} else
break;
}
但是在我看来,这种方法发臭到了天堂.如果管道暂时无法使用,则该线程将继续运行-消耗CPU资源,使用电源,要求将内存页面保留在RAM中等.在我看来,依赖Sleep
或较短超时的线程不会性能良好,这是草率的多线程编程的标志.
But this method stinks to high heaven in my opinion. If a pipe isn't available for awhile, the thread continues to run - sucking up CPU, using power, requiring memory pages to remain in RAM, etc. In my mind, a thread that relies on Sleep
or short timeouts does not perform well and is a sign of sloppy multi-threaded programming.
但是在这种情况下有什么选择呢?
But what's the alternative in this case?
推荐答案
WaitNamedPipe
完全没有用,如果您指定了超时并且没有服务器在等待它,它将仅使用所有cpu.
WaitNamedPipe
is completely useless, and will just use all the cpu if you specify a timeout and there's no server waiting for it.
只需像您一样用Sleep
一遍又一遍地调用CreateFile
,然后将其移动到其他线程即可.没有其他选择.
Just call CreateFile
over and over with a Sleep
like you're doing, and move it to other threads as you see appropriate. There is no API alternative.
WaitNamedPipe
唯一提供的好处"是您是否想知道是否可以连接到命名管道,但明确不想实际打开连接.是垃圾.
The only "benefit" WaitNamedPipe
provides is if you want to know if you can connect to a named pipe but you explicitly don't want to actually open a connection. It's junk.
如果您真的想彻底了解,唯一的选择是
If you really want to be thorough, your only options are
- 确保无论打开命名管道的程序是什么,总是在其连接到命名管道后立即再次调用
CreateNamedPipe
. - 让您的程序实际检查该程序是否正在运行.
- 如果您的意图实际上是没有其他连接,请仍然致电
CreateNamedPipe
,并且当有人连接时,告诉他们离开,直到他们等待了给定的时间,然后关闭管道.
- Ensure that whatever program is opening the named pipe is always calling
CreateNamedPipe
again immediately after it's named pipe is connected to. - Have your program actually check if that program is running.
- If your intent is really not to have additional connections, still call
CreateNamedPipe
, and when someone connects, tell them to go away until they're waited a given amount of time, the close the pipe.
这篇关于什么是WaitNamedPipe的重叠I/O替代品?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!