Skip to main content
 首页 » 编程设计

python之在主进程和子进程中弹出

2025年05月04日8sharpest

以下代码(在主线程中)运行良好,我 grep 一些文件并搜索直到找到前 100 个结果(将结果写入文件),然后退出:

    command = 'grep -F "%s" %s*.txt' % (search_string, DATA_PATH) 
 
    p = Popen(['/bin/bash', '-c', command], stdout = PIPE) 
    f = open(output_file, 'w+') 
    num_lines = MAX_RESULTS 
    while True:   
        line = p.stdout.readline() 
        print num_lines 
        if line != '': 
            f.write(line) 
        num_lines = num_lines - 1 
        if num_lines == 0: 
            break 
        else: 
            break 

Process 子类中使用的代码完全相同,总是在控制台中返回 grep: writing output: Broken pipe:

    class Search(Process): 
        def __init__(self, search_id, search_string): 
            self.search_id = search_id 
            self.search_string = search_string   
            self.grepped = '' 
            Process.__init__(self) 
 
        def run(self): 
            output_file = TMP_PATH + self.search_id 
 
            # flag if no regex chars 
            flag = '-F' if re.match(r"^[a-zA-Z0\ ]*$", self.search_string) else '-P'     
 
            command = 'grep %s "%s" %s*.txt' % (flag, self.search_string, DATA_PATH) 
 
            p = Popen(['/bin/bash', '-c', command], stdout = PIPE) 
            f = open(output_file, 'w+') 
            num_lines = MAX_RESULTS 
            while True:   
                line = p.stdout.readline() 
                print num_lines 
                if line != '': 
                    f.write(line) 
                num_lines = num_lines - 1 
                if num_lines == 0: 
                    break 
                else: 
                    break 

怎么会?如何解决这个问题?

请您参考如下方法:

我可以像这样重现错误消息:

import multiprocessing as mp 
import subprocess 
import shlex 
 
def worker(): 
    proc = subprocess.Popen(shlex.split(''' 
        /bin/bash -c "grep -P 'foo' /tmp/test.txt" 
        '''), stdout = subprocess.PIPE) 
    line = proc.stdout.readline() 
    print(line) 
    # proc.terminate()   # This fixes the problem 
 
if __name__=='__main__': 
    N = 6000 
    with open('/tmp/test.txt', 'w') as f: 
        f.write('bar foo\n'*N)   # <--- Increasing this number causes grep: writing output: Broken pipe 
    p = mp.Process(target = worker) 
    p.start() 
    p.join() 

如果上面的代码没有为您产生错误,请通过增加 N 来增加文件/tmp/test.txt 的大小。 (相反,您可以通过减少 N 来隐藏代码中存在错误的事实。)

如果工作进程在 grep 子进程之前结束,那么 grep 会收到一个 SIGPIPE,告诉它它的标准输出已经关闭。 grep 通过打印响应

grep: writing output: Broken pipe 

到 stderr,它仍在处理的每一行一次。

修复方法是在 worker 结束之前使用 proc.terminate() 终止进程。