2015-10-21 43 views
1

我想寫一個程序通過命名管道與外部程序進行通信。 python腳本不知道外部程序何時打開讀取的命名管道/文件,因此python腳本需要在阻塞模式下打開管道,請參閱open。如果python腳本以非阻塞模式打開並且外部程序尚未打開進行讀取,則open語句將導致錯誤。如何使用Python中的線程模塊寫入命名管道?

因此,要在阻塞模式下打開,python腳本可以在單獨的線程中打開命名管道,並且我嘗試了線程模塊。在下面的例子中,我只是在主線程的命名管道讀,但它產生了同樣的錯誤:

import threading 
import os 

pipe_name = 'pipe_test' 


class WriterNamedPipe(threading.Thread): 

    def __init__(self, filepath, input): 
     ''' 
     Write: generate that will output each line of input 
     ''' 
     # Inherit 
     threading.Thread.__init__(self, verbose = True) 
     self.daemon = False 
     self.filepath = filepath 
     self.input = input 
     self.start() 

    def run(self): 
     # Open blockingly 
     with open(self.filepath, 'w') as f: 
      f.write(self.input) 

if not os.path.exists(pipe_name): 
    os.mkfifo(pipe_name) 

WriterNamedPipe(pipe_name, '1\n' * 100) 

with open(pipe_name, 'r') as f: 
    print f.read() 

,這將導致掛起/凍結:

MainThread: <WriterNamedPipe(Thread-1, initial)>.start(): starting thread 
Thread-1: <WriterNamedPipe(Thread-1, started 1078922160)>.__bootstrap(): thread started 
Thread-1: <WriterNamedPipe(Thread-1, started 1078922160)>.__bootstrap(): normal return 

Compilation hangup 

然而,類似的例如,從here作品,但os.fork

import os, time, sys 
pipe_name = 'pipe_test' 

def child(): 
    pipeout = os.open(pipe_name, os.O_WRONLY) 
    counter = 0 
    while True: 
     time.sleep(1) 
     os.write(pipeout, 'Number %03d\n' % counter) 
     counter = (counter+1) % 5 

def parent(): 
    pipein = open(pipe_name, 'r') 
    while True: 
     line = pipein.readline()[:-1] 
     print 'Parent %d got "%s" at %s' % (os.getpid(), line, time.time()) 

if not os.path.exists(pipe_name): 
    os.mkfifo(pipe_name) 
pid = os.fork()  
if pid != 0: 
    parent() 
else:  
    child() 

爲什麼掛和穿線模塊的例子嗎?

回答

0

由於GIL,這可能不起作用。線程中的open語句會阻塞整個程序。這可以通過使用multiprocessing模塊來避免。