2017-01-06 3 views
1

読み取り専用の名前付きパイプがあり、出力が利用可能になるまでブロックします(ソケット上でselectと同じ動作)。pywin32パイプが空の場合、WaitForMultipleObjectsはブロックされません。

私はWaitForMultipleObjectsが利用可能な出力がない場合ブロックすると仮定しましたが、そうではありません。出力が有効になるまで効率的に待つために何ができるのですか? は、各繰り返しで0バイトを読み出すことができますが、以下のコードではループが100回実行されます。

import win32security, win32file, win32pipe, win32event, win32con 

pipeName = r"\\.\pipe\test-pipe" 

saAttr = win32security.SECURITY_ATTRIBUTES() 

namedPipe = win32pipe.CreateNamedPipe(
    pipeName, 
    win32con.PIPE_ACCESS_DUPLEX | win32con.FILE_FLAG_OVERLAPPED, # open mode 
    win32con.PIPE_TYPE_BYTE, # pipe mode 
    1, # max instances 
    1, # out buffer size 
    1, # in buffer size 
    0, # timeout 
    saAttr) 

fileHandle = win32file.CreateFile(pipeName, 
            win32file.GENERIC_READ, 
            0, None, 
            win32file.OPEN_EXISTING, 
            0, None) 

for i in range(100): 
    # would expect this to block until data is available 
    ret = win32event.WaitForMultipleObjects([fileHandle], 0, win32event.INFINITE) 
    print(i, ret) 
    size = 1 

    buffer, bytesToRead, result = win32pipe.PeekNamedPipe(namedPipe, size) 
    print(buffer, bytesToRead, result) 
    if bytesToRead > 0: 
     res = win32file.ReadFile(namedPipe, size) 

答えて

0

パイプにデータがある場合、私は、WaitForMultipleObjects()ブロックを作るための方法が、チェックするために、代替の非ブロッキング方法はありません。驚いたことにwin32file.GetFileSize()は名前付きパイプで動作します。 Microsoft says it doesn'tですが、それは私にとってはうまくいきます。

コードの効率は議論の余地があります。あなたはそれをアクションhereで見ることができます。

WaitForMultipleObjects()WaitForSingleObject()の予期しない動作の原因何ができるか私が見つけたのいくつかのより多くのポインタ:

  • ファイルは、あなたがWaitFor*()方法はSYNCHRONIZEアクセス権(MSDN reference)を持っている必要がありますして使用したいハンドル
    • 私はよく分かりませんが、これはコンシューマ(クライアント)ではなく、名前付きパイプの作成者(サーバー)にのみ当てはまります。
    • しかしCreateNamedPipe()で作成したファイルハンドルは、私はそれがwin32file.WaitFor*()のpythonラッパー・メソッドを使用した唯一の信頼できるソースは "本ですSYNCHRONIZEアクセス権(MSDN reference
  • を持っているので、これはおそらくあなたの問題の原因ではありませんPython Programming on Win32 "(on Google Books)を参照してください。しかし、彼らは、パイプに書き込まれたデータの代わりに、クライアントが接続するのを待っているようです。
関連する問題