Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 跨多线程管道客户端共享管道句柄_Multithreading_Client_Pipe_Sharing - Fatal编程技术网

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

Multithreading 跨多线程管道客户端共享管道句柄,multithreading,client,pipe,sharing,Multithreading,Client,Pipe,Sharing,我一直在尝试确定是否可以跨管道客户端的线程共享管道句柄(在windows上)。我最初的想法是,我不能,因为除非我同步线程,否则数据可能在服务器上交错显示,从而导致问题。然而,我现在想知道一个pipe_TYPE_MESSAGE和pipe_READMODE_MESSAGE的管道是否允许多线程管道客户端共享一个管道句柄。有人对此有明确的答案吗 我之所以希望跨客户端线程共享单个管道句柄,是为了节省每次发送数据时打开管道的成本。我无法轻松缓存客户端线程的管道句柄,因为我没有创建客户端线程 我包含了一个描述

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

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

我包含了一个描述管道类型模式的片段。我已经强调了这一部分,这让我怀疑消息模式是否能实现我的目标

类型模式

管道的类型模式决定如何将数据写入命名管道 管数据可以作为流或流通过命名管道传输 字节的或作为消息流的。管道服务器指定 调用CreateNamedPipe以创建 命名管道。类型模式对于一个对象的所有实例都必须相同 烟斗

要创建字节类型管道,请指定管道类型或使用默认值 价值数据以字节流的形式写入管道,而 系统不区分以不同格式写入的字节 写操作

要创建消息类型管道,请指定管道类型消息系统 将每次写入管道操作中写入的字节视为 消息单元。系统始终在上执行写操作 消息类型管道,就好像启用了直写模式一样

谢谢,
Nick

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

尽管单扇区写入是原子的,但除非您使用事务(即,创建的句柄是事务句柄;例如,使用CreateFileTransact创建的句柄),否则不能保证多扇区写入是原子的

这表明可以使用事务操作进行原子写入,但我对这种上下文中的事务知之甚少

为了弥补我的不足,我将尝试提出一个解决你问题的替代方案。您的客户端中可以有一个单独的writer线程,该线程对管道具有独占写入权限。当writer线程读取队列并通过管道发送数据时,所有其他线程将其消息推送到FIFO队列。这是一种比锁定整个写操作更好的方法,因为入/出队列操作要快得多,线程不会被长时间阻塞


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

这听起来像是你说的,因为WriteFile()是线程安全的,我的客户端将使用它,数据不会被交错。这样看来,操作系统正在同步这些调用。对吗?因此,如果两个线程使用相同的文件句柄,选择一个相似但略有不同的示例,它们各自向文件写入一些字节缓冲区,无论客户端缓冲区是否大于操作系统或运行时库缓冲区,这些字节都不会交错,因此必须将其自身分块写入多个写入?对于我的轻率回答,我深表歉意:(.读了你的评论后,我意识到我的错误是非常错误的,我更新了我的答案。请重新检查我的答案。这又回到了我原来的问题。我假设面向字节的管道可能具有交错“缓冲区”的潜力。面向消息的管道给我的印象是,可能操作系统正在做一些特殊的事情o确保管道中的每个写入缓冲区都完好无损,从而可以处理我概述的多个客户端线程共享同一管道句柄的情况。顺便说一下,我用管道类型文档中的一个片段更新了我的问题。我认为将管道类型设置为管道类型消息不会解决问题。如果设置了字节模式然后,操作系统不区分在不同写入操作中写入的数据。因此,您可以在读取端从多个写入操作中读取字节。如果模式设置为MESSAGE,则使用write写入的数据就像传输数据包。读取操作一次读取一个数据包。但是,这并不意味着操作系统将锁定写入正如我们所讨论的,防止数据交错的操作。写入单个扇区是原子的,不必写入多个扇区。