如何使用Python中的线程模块写入命名管道?

问题描述 投票:1回答:2

我正在尝试编写一个程序,通过命名管道与外部程序进行通信。 python脚本不知道外部程序何时打开命名管道/文件进行读取,因此python脚本需要以阻塞模式打开管道,请参阅open。如果python脚本以非阻塞模式打开并且外部程序尚未打开以进行读取,则open语句将导致错误。

所以要在阻塞模式下打开,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()

为什么线程模块的示例挂起?

python linux multithreading named-pipes
2个回答
0
投票

由于GIL,这可能不起作用。线程中的open语句阻塞整个程序。这可以通过使用multiprocessing模块来避免。


0
投票

当@hakanc指出由于GIL它会阻止你的过程。 os.fork正在工作,因为它实际上产生了一个子进程而不是线程,而GIL没有阻塞它。

© www.soinside.com 2019 - 2024. All rights reserved.