CreateNamedPipe和WaitForMultipleObjectsEx

时间:2016-07-15 02:26:37

标签: multithreading winapi

我有一个创建命名管道的线程:

CreateNamedPipe('\\\\.\\pipe\\dirwatcher', PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 1, 1, 0, null);

然后我产生另一个名为“poller”的线程,这个有一个监视文件。我想让它等待这个管道,所以我可以打断无限轮询。

我在这个轮询器线程中创建管道,如下所示:

pipe = CreateFile('\\\\.\\pipe\\dirwatcher', GENERIC_READ, FILE_SHARE_READ, null, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, null);

然后我试着像这样等待这个管道:

对于这种情况,LP_HANDLES是一个只包含一个元素pipe

的数组
rez_wait = WaitForMultipleObjectsEx(LP_HANDLES.length, LP_HANDLES, false, INFINITE, true);
console.log('rez_wait:', rez_wait);

然而,这根本不会等待,并且会立即返回0.我在创建命名管道和连接它时都使用了重叠标志。有谁知道如何解决这个问题?

这是我的代码,具体是js-ctypes:

创建管道: https://github.com/Noitidart/jscFileWatcher/blob/master/DirectoryWatcherWorkerSubscript.js#L91-L99

在轮询线程中获取管道: https://github.com/Noitidart/jscFileWatcher/blob/master/DirectoryWatcherPollWorker.js#L53-L64

等待管道: https://github.com/Noitidart/jscFileWatcher/blob/master/DirectoryWatcherPollWorker.js#L89

由于

1 个答案:

答案 0 :(得分:1)

您不能等待备注中所述的使用WaitForMultipleObjectsEx的管道:

  

WaitForMultipleObjectsEx 函数可以指定 lpHandles 数组中以下任何对象类型的句柄:

     
      
  • 更改通知
  •   
  • 控制台输入
  •   
  • 事件
  •   
  • 内存资源通知
  •   
  • 互斥
  •   
  • 过程
  •   
  • 信号量
  •   
  •   
  • 等待计时器
  •   

您必须使用PeekNamedPipe执行此作业(如果管道为空,则不会等待)或者您只需在管道上执行阻止ReadFile

我前一段时间遇到过同样的问题,我已经通过等待WaitForSingleObject的事件解决了这个问题,如果我已将某些内容放入管道中,我会设置该事件。我必须这样做,因为我有几个管道,只有一个"读者线程"由事件唤醒并使用PeekNamedPipe来检查哪个管道包含数据(我并不想创建几个"读取器线程"它们在{{1}内被阻止呼叫)。

无论如何,我很奇怪您可以使用ReadFile等待除管道之外的任何事情(非常烦人!)。