2009-11-11 141 views
2

我写了一些数据到管道 - 可能是很多数据和随机间隔。如何从管道读取数据?多线程:读取/写入管道

这是确定:

    在主线程
  • (当前进程)创建两个以上线程(2,3)
  • 第二线程有时写入管道(和flush-ES管道? )
  • 第三线程具有无限循环读取管道(然后睡了一段时间)

这是到目前为止,正确吗?

现在,有一些事情我不明白:

  • 我必须锁(互斥?)上写管道?
  • IIRC,当写入管道及其缓冲区已满时,写入结束会阻塞,直到我读取已写入的数据,对吧?如何检查管道中的读取数据,不要太频繁,不要太少?所以第二个线程不会阻止?有没有像select管道?
  • 可以将管道设置为无缓冲区,或者我必须定期刷新它 - 哪一个更好?
  • 我应该多创建一个线程,只是为了在写入后刷新管道?因为冲洗块,以及缓冲区已满,对吧?我只是不想在第一和第二线程阻塞....

[编辑] 对不起,我想这个问题是平台无关,但以防万一:我是从Win32的角度看这个可能MinGW的ç...

+1

这些都是很好的问题。如果你将自己的问题分解出来并提供你正在考虑的方法的代码片段,你会得到更好的回应。另外,你没有提到有关语言或平台的任何信息。 – 2009-11-11 03:28:58

+0

同意凯利。我们需要更多的信息。所有这些问题都可以有平台和语言特定的答案。另外,您打算用于“管道”的数据结构将是有用的信息。 – 2009-11-11 23:31:57

+0

哦,对不起,我认为平台并不那么重要,因为我认为这个问题与技术有关。但我只是更新了这个问题,谢谢你的建议。什么样的数据结构,只有缓冲区,这只是一个数组...。 – 2009-11-12 00:09:36

回答

2

我不会回答你所有的问题在这里,因为有很多人,但在回答:

我必须锁管(互斥?)写上?

这个问题的答案是平台特定的,但在大多数情况下,我会猜测是的

这涉及到管道上的写入/读取操作是否为原子。如果的读数为写入操作是非原子操作(很可能是写操作),那么您需要在写入和读取时锁定管道以防止竞争条件。

例如,可以说在管道上写入编译成机器代码2说明:

INSTRUCTION 1 
INSTRUCTION 2 

比方说,如果你把这些2个指令和你阅读线程试图之间的线程上下文切换读取处于中间状态的管道。这可能会导致崩溃或(更糟糕的)数据损坏,这些数据损坏通常会在代码中的其他位置出现崩溃。这通常是由于竞争条件而产生的,这些条件通常是非确定性的并且难以诊断或再现。

一般来说,除非您可以保证所有线程都将使用原子指令集访问共享资源,否则必须使用互斥锁或临界区域

+0

当管道操作系统序列化时,对管道的'write()'对于短消息是安全的。如果你依赖于这个,强烈建议**只使用长度为2的小功率的消息(即,可以正好整除成一个内存页面),这样写入就不会停止,书面信息。 – 2010-05-13 08:07:42