multithreading - 跨多线程管道客户端共享管道句柄

标签 multithreading client pipe sharing

我一直在尝试确定是否可以跨管道客户端的线程共享管道句柄(在 Windows 上)。我最初的想法是我不能,因为除非我同步线程,否则数据可能会在服务器上交错显示,从而导致问题。但是我现在想知道 PIPE_TYPE_MESSAGE 和 PIPE_READMODE_MESSAGE 的管道是否允许我让多线程管道客户端共享一个管道句柄。有人对此有明确的答案吗?

我希望跨客户端线程共享单个管道句柄的原因是为了节省每次发送数据时打开管道的成本。我无法轻松缓存客户端线程的管道句柄,因为我没有创建客户端线程。

我已经包含了来自 https://msdn.microsoft.com/en-us/library/windows/desktop/aa365605(v=vs.85).aspx 的片段其中描述了管道类型模式。我突出显示了让我想知道消息模式是否会完成我正在尝试做的事情的部分。

...

Type Mode

The type mode of a pipe determines how data is written to a named pipe. Data can be transmitted through a named pipe as either a stream of bytes or as a stream of messages. The pipe server specifies the pipe type when calling CreateNamedPipe to create an instance of a named pipe. The type modes must be the same for all instances of a pipe.

To create a byte-type pipe, specify PIPE_TYPE_BYTE or use the default value. The data is written to the pipe as a stream of bytes, and the system does not differentiate between the bytes written in different write operations.

To create a message-type pipe, specify PIPE_TYPE_MESSAGE. The system treats the bytes written in each write operation to the pipe as a message unit. The system always performs write operations on message-type pipes as if write-through mode were enabled.

...

谢谢, 尼克

最佳答案

ReadFile 和 WriteFile WinAPI 函数都是线程安全的。与我之前写的不同(对此感到抱歉),此线程安全性不保证来自不同线程的并发写入不会交错。换句话说,不能保证首先开始写入数据的线程会在其他线程获得写访问权之前完成。来自 MSDN:

Although a single-sector write is atomic, a multi-sector write is not guaranteed to be atomic unless you are using a transaction (that is, the handle created is a transacted handle; for example, a handle created using CreateFileTransacted).

这表明可以使用事务处理操作进行原子写入,但我对这种情况下的事务知之甚少。

为了 self 救赎,我将尝试针对您的问题提出替代解决方案。您可以在客户端中有一个单独的writer 线程,该线程对管 Prop 有独占写入权限。所有其他线程将它们的消息推送到 FIFO 队列,而写入线程读取队列并通过管道发送数据。这是比锁定整个写操作更好的方法,因为入队/出队操作要快得多,并且线程不会被阻塞太久。

您可以以写入线程可以等待它的方式实现队列,并且仅当队列中有消息时才唤醒。否则,写入线程将有一个繁忙的循环,这是一个令人讨厌的解决方案。

关于multithreading - 跨多线程管道客户端共享管道句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31509028/

相关文章:

objective-c - 如何在非 ARC 世界中使用 NSMutableDictionary 避免 EXC_BAD_ACCESS?

Java嵌套同步

Java Sockets - 将数据从服务器发送到客户端

cocoa - NSTask 不会终止

bash - 如何在 Bash 中以分隔符 ` 分割字符串?

java - 为什么 ThreadPoolExecutor 的参数是 BlockingQueue?

C pthread_t 读/写允许吗?

Python 客户端-服务器脚本挂起,直到我按 [enter]

javascript - 使用 ejabberd、stropice.js、stropice.muc.js 和 stropice.roster.js 的存在问题

linux - 如何通过 SFTP 将远程服务器上 LS 的输出传输到本地文件系统?