Python 子进程因命名管道而挂起

2024-01-31

I'm 挣扎在试图模仿这个简单的片段bash:

$ cat /tmp/fifo.tub &                                                            
[1] 24027
$ gunzip -c /tmp/filedat.dat.gz > /tmp/fifo.tub                                                              
line 01
line 02
line 03
line 04
line 05
line 06
line 07
line 08
line 09
line 10
[1]+  Done                    cat /tmp/fifo.tub

基本上我尝试过这个subprocess方法:

# -*- coding: utf-8 -*-

import os
import sys
import shlex
import pprint
import subprocess

def main():

    fifo = '/tmp/fifo.tub'
    filedat = '/tmp/filedat.dat.gz '
    os.mkfifo(fifo,0777)
    cat  = "cat %s" % fifo
    args_cat = shlex.split(cat)
    pprint.pprint(args_cat)

    cat = subprocess.Popen( args_cat,
                            close_fds=True,
                            preexec_fn=os.setsid)

    print "PID cat: %s" % cat.pid

    f = os.open(fifo ,os.O_WRONLY)

    gunzip = 'gunzip -c  %s' %  (filedat)
    args_gunzip = shlex.split(gunzip)
    pprint.pprint(args_gunzip)

    gunzip = subprocess.Popen( args_gunzip,
                               stdout = f,
                               close_fds=True,
                               preexec_fn=os.setsid)

    print "PID gunzip: %s" % gunzip.pid

    while not cat.poll():
        # hangs for ever
        pass
    return True

if __name__=="__main__":
    main()

cat过程never ends.

或者我尝试绕过这个问题threads但我得到同样的结果。

import os
import sys
import shlex
import pprint
import subprocess
import threading

class Th(threading.Thread):
    def __init__(self,cmd,stdout_h=None):
        self.stdout = None
        self.stderr = None
        self.cmd = cmd
        self.stdout_h = stdout_h

        self.proceso = None
        self.pid = None

        threading.Thread.__init__(self)

    def run(self):
        if self.stdout_h:
            self.proceso = subprocess.Popen(self.cmd,
                                 shell=False,
                                 close_fds=True,
                                 stdout=self.stdout_h)

        else:
            self.proceso = subprocess.Popen( self.cmd,
                                  close_fds=True,
                                  shell=False)
        print "PID: %d" % self.proceso.pid   


def main():

    fifo = '/tmp/fifo.tub'
    filedat = '/tmp/filedat.dat.gz '

    try:
        os.unlink(fifo)
    except:
        pass
    try:
       os.mkfifo(fifo,0777)
    except Exception , err:
       print "Error '%s' tub %s." % (err,fifo)
       sys.exit(5)

    cat  = "cat %s" % fifo
    args_cat = shlex.split(cat)
    pprint.pprint(args_cat)

    cat = Th(cmd=args_cat)
    cat.start()

    try:
        f = os.open(fifo ,os.O_WRONLY)
    except Exception, err:
        print  "Error '%s' when open fifo %s " % (err,fifo)
        sys.exit(5)

    gunzip = 'gunzip -c  %s ' %  (filedat)
    args_gunzip = shlex.split(gunzip)
    pprint.pprint(args_gunzip)

    gunzip = Th(cmd=args_gunzip,stdout_h=f)
    gunzip.start()
    gunzip.join()
    cat.join()

    while  gunzip.proceso.poll() is None:
        pass

    if  cat.proceso.poll() is None:
        print "Why?"
        cat.proceso.terminate() 
    return True

if __name__=="__main__":
    main()

我显然错过了一些东西,非常欢迎任何帮助。


您没有关闭 FIFO 文件描述符,因此 cat 只是挂在那里,认为还会有更多的事情发生。

我认为您也可以使用 .wait() 方法来执行与 while 循环相同的操作。

# -*- coding: utf-8 -*-

import os
import sys
import shlex
import pprint
import subprocess

def main():

    fifo = '/tmp/fifo.tub'
    filedat = '/tmp/filedat.dat.gz '
    os.mkfifo(fifo,0777)
    cat  = "cat %s" % fifo
    args_cat = shlex.split(cat)
    pprint.pprint(args_cat)

    cat = subprocess.Popen( args_cat,
                            close_fds=True,
                            preexec_fn=os.setsid)

    print "PID cat: %s" % cat.pid

    f = os.open(fifo ,os.O_WRONLY)

    gunzip = 'gunzip -c  %s' %  (filedat)
    args_gunzip = shlex.split(gunzip)
    pprint.pprint(args_gunzip)

    gunzip = subprocess.Popen( args_gunzip,
                               stdout = f,
                               close_fds=True,
                               preexec_fn=os.setsid)

    print "PID gunzip: %s" % gunzip.pid

    gunzip.wait()
    print "gunzip finished"
    os.close(f)
    cat.wait()
    print "cat finished"

    return True

if __name__=="__main__":
    main()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 子进程因命名管道而挂起 的相关文章

随机推荐

  • 您可以使用多个过滤器调用 Directory.GetFiles() 吗?

    我正在尝试使用Directory GetFiles 方法来检索多种类型的文件列表 例如mp3 s and jpg的 我尝试过以下两种方法 但没有成功 Directory GetFiles C path mp3 jpg SearchOptio
  • asterisk agi (php) 文件调试

    有谁知道调试 asterisk 的 agi secript a2billing php 所需的步骤 如果我从 Linux 控制台调用 php cli 我就可以远程调试它 但如果它从 asterisk 内部运行 则不起作用 知道如何调试它吗
  • 更改Fiddler根证书以成功解密HTTPS

    有没有办法更改Fiddler的根证书 当客户端应用程序使用证书固定并且我可以访问密钥库 其证书受到客户端应用程序信任 时 我希望使用它 我想你是在问 我可以更改 Fiddler 用于特定站点的证书吗 而不是root证书 用于所有站点 是的
  • 为什么使用 std::make_* 而不是构造函数更好?

    STL中有一些函数以make 前缀如std make pair std make shared std make unique等等 为什么使用它们而不是简单地使用构造函数是更好的做法 auto pair2 std pair lt int d
  • 添加 VPC 配置后调用 lambda 超时

    我正在使用无服务器框架来创建 lambda 我创建了一个简单的 Lambda 函数 它从 Mongo 实例进行查询并返回响应 最初 我使用 publicIp 创建了 Mongo 实例 并让 Lambda 使用 publicIP 访问该实例
  • 在 mysql 脚本中静默“Query OK 0 row受影响”输出

    我有一个创建多个存储过程的 MySQL 脚本 我想让大家沉默 Query OK 0 rows affected 0 00 sec 当我运行时出现的消息 source MY SCRIPT sql 它变成了一个很长的列表 我有时会忘记在开发过程
  • Visual Studio 2010 中的 Microsoft 图表控件?

    这可能吗 我安装了它们 但它们没有出现 我必须导入它们还是什么 如果在工具箱中看不到 Chart 控件 请右键单击工具箱 选择 选择项 然后在 NET Framework 组件 选项卡中选择以下命名空间 System Web UI Data
  • 设置带有子包的 python 包的正确方法

    我正在尝试在 python 中设置一个带有子包的包 这是我目前拥有的树结构 myPackage init py mySubPackage1 foo2 py foo py init py mySubPackage2 bar2 py bar p
  • Android SQLiteOpenHelper - 每个表都有不同的类?

    我正在读这篇文章 http www vogella com tutorials AndroidSQLite article html http www vogella com tutorials AndroidSQLite article
  • 像 TinyPNG 这样的图像优化 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我在 Google 上搜索过一个好的 Mass Image Optimizer 可以在 Windows
  • 如何从 Android 中的菜单项调用 Activity?

    我试图通过单击菜单按钮来调用 startActivity myIntent 但我的应用程序此时崩溃了 通过常规按钮单击 相同的 startActivity 调用可以正常工作 因此 我认为菜单按钮缺少有关上下文的信息 或者也许我在这里完全偏离
  • 将 jQueryUI 可排序列表与表单一起使用

    我正在使用 jQueryUI 创建一个可排序列表 并且 UI 部分工作得很好 因为我可以根据需要在网页上对项目进行排序 但我不知道排序列表的顺序是如何包含在 POST 中的 我对 javascript 完全是菜鸟 所以如果这真的很简单 请原
  • TimeSpan 转 ISO8601 持续时间格式字符串

    任何人都可以建议如何将时间跨度或整数转换为 ISO8601 持续时间字符串 如中所述http en wikipedia org wiki ISO 8601 Durations http en wikipedia org wiki ISO 8
  • WPF 验证器类似于 ASP.NET 中的验证器

    我们如何在 WPF 应用程序中实现类似于 ASP NET 应用程序的验证器 如必填字段验证器 提前致谢 None
  • 如何在 Cypress e2e 测试中使用 Angular Store

    我需要在我的 Angular Store 中注入一个值 调度一个操作 以使我的 Cypress e2e 测试正常工作 事实上 我需要我的商店包含 isLoggedIn true 来访问应用程序中的任何页面 否则用户将被重定向到登录页面 我在
  • 使用 visNetwork 动态更新 R 中的节点

    下面的快照视觉效果是使用 visNetwork 包创建的 我这里的要求是我必须对边缘进行硬编码 并且在使用 visHierarchicalLayout 之后 我无法按顺序看到它们 请帮助我采用动态方法 这样无论有多少个数字 我都会得到连续的
  • 查找字符串中某个字符的所有出现位置

    我试图找到所有出现的 在一个字符串中 def findSectionOffsets text startingPos 0 endPos len text for position in text find startingPos endPo
  • Eclipse 字体缩小和放大问题

    如何在 Eclipse 中放大和缩小文本 我找到了插件 但无法手动安装 请告诉我在 Eclipse 中安装不同插件的过程 我在使用 Android 开发工具 Eclipse 遇到很多问题后问了这个问题 查看此链接 您一定会喜欢它Eclips
  • 使用 PHP 整理多个 JavaScript 文件是否比单独包含它们更快?

    我知道提供多个小文件比提供一个大文件要慢得多 这就是为什么最好使用单个 CSS 文档和精灵表 一段时间以来 我还尝试在尽可能少的文件中包含尽可能多的 JavaScript 以避免查看者多次请求更多文件 但是在同一个文档中包含各种明显不同的任
  • Python 子进程因命名管道而挂起

    I m 挣扎在试图模仿这个简单的片段bash cat tmp fifo tub 1 24027 gunzip c tmp filedat dat gz gt tmp fifo tub line 01 line 02 line 03 line