2015-12-29 8 views
7

पर os.pipe पर पढ़ें यह सवाल - How to read from an os.pipe() without getting blocked? - अगर os.pipe लिनक्स के लिए किसी भी डेटा की जांच करने के लिए कैसे एक समाधान से पता चलता है, और इस के लिए आप गैर अवरुद्ध मोड में पाइप डालने के लिए की जरूरत है:गैर अवरुद्ध विंडोज

import os, fcntl 
fcntl.fcntl(thePipe, fcntl.F_SETFL, os.O_NONBLOCK) 

विंडोज़ पर हम इस राशि:

ImportError: No module named fcntl 

लेकिन os.pipe है:

>>> os.pipe() 
(3, 4) 

तो, क्या विंडोज़ पर os.pipe की सामग्री को पढ़ने या देखने के लिए गैर-अवरुद्ध करना संभव है?

+1

भी देखें http://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in-python (डुप्लिकेट नहीं है लेकिन कुछ ओवरलैप है)। – ideasman42

उत्तर

7

स्टैक ओवरव्लो के माध्यम से कुछ समय के लिए खोदने के बाद अपने स्वयं के प्रश्न का उत्तर दें।

अद्यतन: चीजें बदलती हैं @ हैरी जोहानस्टन।

पहले जवाब में था कोई, यह गैर अवरुद्ध विंडोज पर os.pipe पर पढ़ें करने के लिए संभव नहीं है। this answer से मुझे लगता है कि मिल गया है:

गैर अवरुद्ध/अतुल्यकालिक मैं/Windows में ओ 'ओवरलैप' है के लिए शब्द - कि क्या आप पर विचार करना चाहिए।

विंडोज पर os.pipeCreatePipe एपीआई (here देख सकते हैं और ... ठीक है, मुझे os.pipe कोड Python sources में नहीं मिल सकता है) के माध्यम से कार्यान्वित किया जाता है। CreatePipe अज्ञात पाइप बनाता है, और anonymous pipes do not support asynchronous I/O

लेकिन तब@HarryJohnston टिप्पणी की है कि SetNamedPipeHandleState डॉक गैर अवरुद्ध मोड के लिए अनाम पाइप डालने के लिए अनुमति देता है। मैंने परीक्षण लिखा और यह OSError: [Errno 22] Invalid argument के साथ विफल रहा। त्रुटि संदेश गलत लग रहा था, इसलिए मैंने यह जांचने की कोशिश की कि डेटा उपलब्ध नहीं होने पर गैर-अवरुद्ध पढ़ने वाले ऑपरेशन पर रिटर्न परिणाम क्या होना चाहिए, और MSDN note on named pipe modes पढ़ने के बाद मुझे पता चला कि यह ERROR_NO_DATA होना चाहिए जिसमें एक int मान 232 है। ctypes.WinError() को कॉल करना अपवाद संचालक की उम्मीद खुलासा [Error 232] The pipe is being closed.

तो, इस सवाल का जवाब हाँ है, यह विंडोज पर os.pipe पर गैर-अवरुद्ध पढ़ ऐसा करने के लिए संभव है, और यहाँ सबूत है:

import msvcrt 
import os 

from ctypes import windll, byref, wintypes, GetLastError, WinError 
from ctypes.wintypes import HANDLE, DWORD, POINTER, BOOL 

LPDWORD = POINTER(DWORD) 

PIPE_NOWAIT = wintypes.DWORD(0x00000001) 

ERROR_NO_DATA = 232 

def pipe_no_wait(pipefd): 
    """ pipefd is a integer as returned by os.pipe """ 

    SetNamedPipeHandleState = windll.kernel32.SetNamedPipeHandleState 
    SetNamedPipeHandleState.argtypes = [HANDLE, LPDWORD, LPDWORD, LPDWORD] 
    SetNamedPipeHandleState.restype = BOOL 

    h = msvcrt.get_osfhandle(pipefd) 

    res = windll.kernel32.SetNamedPipeHandleState(h, byref(PIPE_NOWAIT), None, None) 
    if res == 0: 
     print(WinError()) 
     return False 
    return True 


if __name__ == '__main__': 
    # CreatePipe 
    r, w = os.pipe() 

    pipe_no_wait(r) 

    print os.write(w, 'xxx') 
    print os.read(r, 1024) 
    try: 
    print os.write(w, 'yyy') 
    print os.read(r, 1024) 
    print os.read(r, 1024) 
    except OSError as e: 
    print dir(e), e.errno, GetLastError() 
    print(WinError()) 
    if GetLastError() != ERROR_NO_DATA: 
     raise 
+0

पाइप्स (अज्ञात पाइप समेत) LAN प्रबंधक के साथ पिछड़ा संगतता के लिए I/O को अनब्लॉक करने का समर्थन करता है। [SetNamedPipeHandleState] देखें (https://msdn.microsoft.com/en-us/library/windows/desktop/aa365787 (v ​​= vs.85) .aspx)। लेकिन मुझे नहीं पता कि पाइथन इसका समर्थन करता है या नहीं। –

+0

@ हैरीजोहनस्टन दिलचस्प है। परीक्षण करने के लिए कुछ सबूत कोड की आवश्यकता है यदि यह वास्तव में काम करता है। –

+0

@ हैरीजोस्टन ने यह काम किया। =) मैंने यह भी सोचा कि मैं इसे इस समस्या को ठीक करने के लिए लागू कर सकता हूं https://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in-python लेकिन अटक गया। शायद बाद में। –

संबंधित मुद्दे