python - 在 python2.7 中使用 python 读写 block 打开

标签 python subprocess deadlock popen

我正面临另一位用户@AMisra 不久前发布的类似问题,但没有收到明确的答复。问题是因为我使用的是第三方代码,不能修改太多。我有一个在代码中被多次调用的函数来创建一个子进程,将数据写入标准输入然后读取。它只是卡在这一行

line = self.classifier.stderr.readline()

请注意,我不能使用communicate:因为func2(classifier, vectors) 需要多次调用,它会抛出异常。

import subprocess
import paths
import os.path

class CRFClassifier:
    def __init__(self, name, model_type, model_path, model_file, verbose):
        self.verbose = verbose
        self.name = name
        self.type = model_type
        self.model_fname = model_file
        self.model_path = model_path

        if not os.path.exists(os.path.join(self.model_path, self.model_fname)):
            print 'The model path %s for CRF classifier %s does not exist.' % (os.path.join(self.model_path, self.model_fname), name)
            raise OSError('Could not create classifier subprocess')


        self.classifier_cmd = '%s/crfsuite-stdin tag -pi -m %s -' % (paths.CRFSUITE_PATH, 
                             os.path.join(self.model_path, self.model_fname))
#        print self.classifier_cmd
        self.classifier = subprocess.Popen(self.classifier_cmd, shell = True, stdin = subprocess.PIPE, stderr = subprocess.PIPE)

        if self.classifier.poll():
            raise OSError('Could not create classifier subprocess, with error info:\n%s' % self.classifier.stderr.readline())

        #self.cnt = 0


    def classify(self, vectors):
#        print '\n'.join(vectors) + "\n\n"

        self.classifier.stdin.write('\n'.join(vectors) + "\n\n")

        lines = []
        line = self.classifier.stderr.readline()
        while (line.strip() != ''):
#            print line
            lines.append(line)
            line = self.classifier.stderr.readline()


        if self.classifier.poll():
            raise OSError('crf_classifier subprocess died')

        predictions = []
        for line in lines[1 : ]:
            line = line.strip()
#            print line
            if line != '':
                fields = line.split(':')
#                print fields
                label = fields[0]
                prob = float(fields[1])
                predictions.append((label, prob))

        seq_prob = float(lines[0].split('\t')[1])

        return seq_prob, predictions


    def poll(self):
        """
        Checks that the classifier processes are still alive
        """
        if self.classifier is None:
            return True
        else:
            return self.classifier.poll() != None

分类器对象是为输入文件创建的,它是一个带有句子列表的文档,在创建时它还使用这个句子列表执行外部命令。然后在一个单独的函数中处理每个句子,为每个句子提供一个单独的向量。这个新向量被传递给分类函数。

def func2():
    classifier=create a classifier object for an input file, this executes the external command
    for sentence in sentences:
        vectors=process(sentence)# some external function
        classifier.classify(features)  

最佳答案

classify方法而不是构造函数中初始化self.classifier,并使用Popen()。还需要使用 stdout 而不是 stderr

关于python - 在 python2.7 中使用 python 读写 block 打开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42308126/

相关文章:

c++ - 为什么这个双重互斥锁不会造成死锁呢?

python - 我想计算每个不同组的行数

python - 如何突然终止正在进行的处理

python - 如何动态显示 tkinter 模块中的数据-Python

python - 子进程输出中未正确显示 Unicode 字符

python - 在 Python 2.5 及更低版本上创建不使用 shell 的可执行进程

asp.net - 请求同一服务器时 IIS ASP.NET WebApi 死锁

deadlock - 可重复使用的Barrier解决方案陷入僵局?

python - 使matplotlib python中的hexbin填充方轴上的空白区域?

python - 使用全息 View 时如何自动隐藏 Bokeh 工具栏