使用同步 NamedPipes 同步读写
Posted
技术标签:
【中文标题】使用同步 NamedPipes 同步读写【英文标题】:Synchronizing reading and writing with synchronous NamedPipes 【发布时间】:2009-02-09 02:46:28 【问题描述】:使用
创建命名管道服务器hPipe = CreateNamedPipe( zPipePath,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_READMODE_BYTE,
PIPE_UNLIMITED_INSTANCES,
8192, 8192, NMPWAIT_USE_DEFAULT_WAIT, NULL)
然后我们立即调用:
ConnectNamedPipe( hPipe, BYVAL %NULL )
在客户端连接之前阻塞。
然后我们直接进入 ReadFile( hPipe, ...
问题在于客户端需要有限的时间来准备和写入所有 fcgi 请求参数。这通常在 Pipe Server 执行其 ReadFile() 之前尚未完成。因此,读取文件操作在管道中找不到任何数据,并且该过程失败。
在客户端连接到 NamedPipe 后,是否有一种机制来判断 Write() 何时发生/完成?
如果我可以控制 Client 进程,我可以使用通用的 Mutex,但我没有,而且我真的不想为了解决这个问题而进入 I/O 完成端口!
我当然可以使用一个简单的计时器来等待 60m/s 左右,这通常是足够的时间来完成写入,但这是一个可怕的 hack。
【问题讨论】:
【参考方案1】:我不确定您使用的是什么语言 - 我不认识像
这样的表达方式PIPE_TYPE_BYTE OR %PIPE_WAIT OR %PIPE_READMODE_BYTE
但在我看来,服务器的 ReadFile() 应该阻塞,直到客户端写入数据。
看起来不正确(但不应该伤害任何东西)的一件事是使用 NMPWAIT_USE_DEFAULT_WAIT
- 该值是供客户在调用 WaitNamedPipe()
时使用的。
你能看看这 2 个 C++ 程序是否像你期望的那样交互(即,服务器阻塞直到客户端写东西)?我从 Jones/Ohlund 的《Windows 网络编程》一书中获取了这些程序。ReadFile()
调用中的服务器按预期阻止了我:
- server.cpp
// Server.cpp
#include <windows.h>
#include <stdio.h>
void main(void)
HANDLE PipeHandle;
DWORD BytesRead;
CHAR buffer[256];
if ((PipeHandle = CreateNamedPipe("\\\\.\\Pipe\\Jim",
PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1,
0, 0, 1000, NULL)) == INVALID_HANDLE_VALUE)
printf("CreateNamedPipe failed with error %d\n",
GetLastError());
return;
printf("Server is now running\n");
if (ConnectNamedPipe(PipeHandle, NULL) == 0)
printf("ConnectNamedPipe failed with error %d\n",
GetLastError());
CloseHandle(PipeHandle);
return;
if (ReadFile(PipeHandle, buffer, sizeof(buffer),
&BytesRead, NULL) <= 0)
printf("ReadFile failed with error %d\n", GetLastError());
CloseHandle(PipeHandle);
return;
printf("%.*s\n", BytesRead, buffer);
if (DisconnectNamedPipe(PipeHandle) == 0)
printf("DisconnectNamedPipe failed with error %d\n",
GetLastError());
return;
CloseHandle(PipeHandle);
- 客户端.cpp
// Client.cpp
#include <windows.h>
#include <stdio.h>
#define PIPE_NAME "\\\\.\\Pipe\\jim"
void main(void)
HANDLE PipeHandle;
DWORD BytesWritten;
if (WaitNamedPipe(PIPE_NAME, NMPWAIT_WAIT_FOREVER) == 0)
printf("WaitNamedPipe failed with error %d\n",
GetLastError());
return;
// Create the named pipe file handle
if ((PipeHandle = CreateFile(PIPE_NAME,
GENERIC_READ | GENERIC_WRITE, 0,
(LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL)) == INVALID_HANDLE_VALUE)
printf("CreateFile failed with error %d\n", GetLastError());
return;
if (WriteFile(PipeHandle, "This is a test", 14, &BytesWritten,
NULL) == 0)
printf("WriteFile failed with error %d\n", GetLastError());
CloseHandle(PipeHandle);
return;
printf("Wrote %d bytes", BytesWritten);
CloseHandle(PipeHandle);
【讨论】:
以上是关于使用同步 NamedPipes 同步读写的主要内容,如果未能解决你的问题,请参考以下文章
uniapp同步读写缓存 - 解决uni.setStorageSyncuni.getStorageSync数据不同步的问题 - async/await异步同步