<i id='HG1TI'><tr id='HG1TI'><dt id='HG1TI'><q id='HG1TI'><span id='HG1TI'><b id='HG1TI'><form id='HG1TI'><ins id='HG1TI'></ins><ul id='HG1TI'></ul><sub id='HG1TI'></sub></form><legend id='HG1TI'></legend><bdo id='HG1TI'><pre id='HG1TI'><center id='HG1TI'></center></pre></bdo></b><th id='HG1TI'></th></span></q></dt></tr></i><div id='HG1TI'><tfoot id='HG1TI'></tfoot><dl id='HG1TI'><fieldset id='HG1TI'></fieldset></dl></div>
<legend id='HG1TI'><style id='HG1TI'><dir id='HG1TI'><q id='HG1TI'></q></dir></style></legend>
    • <bdo id='HG1TI'></bdo><ul id='HG1TI'></ul>

    <small id='HG1TI'></small><noframes id='HG1TI'>

    <tfoot id='HG1TI'></tfoot>

        Python C 程序子进程在“for line in iter"处挂起

        Python C program subprocess hangs at quot;for line in iterquot;(Python C 程序子进程在“for line in iter处挂起)

        • <tfoot id='xHMwN'></tfoot>

          <legend id='xHMwN'><style id='xHMwN'><dir id='xHMwN'><q id='xHMwN'></q></dir></style></legend>

            <tbody id='xHMwN'></tbody>

              <small id='xHMwN'></small><noframes id='xHMwN'>

            1. <i id='xHMwN'><tr id='xHMwN'><dt id='xHMwN'><q id='xHMwN'><span id='xHMwN'><b id='xHMwN'><form id='xHMwN'><ins id='xHMwN'></ins><ul id='xHMwN'></ul><sub id='xHMwN'></sub></form><legend id='xHMwN'></legend><bdo id='xHMwN'><pre id='xHMwN'><center id='xHMwN'></center></pre></bdo></b><th id='xHMwN'></th></span></q></dt></tr></i><div id='xHMwN'><tfoot id='xHMwN'></tfoot><dl id='xHMwN'><fieldset id='xHMwN'></fieldset></dl></div>
              • <bdo id='xHMwN'></bdo><ul id='xHMwN'></ul>
                1. 本文介绍了Python C 程序子进程在“for line in iter"处挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  好的,我正在尝试从 python 脚本运行 C 程序.目前我正在使用一个测试 C 程序:

                  Ok so I'm trying to run a C program from a python script. Currently I'm using a test C program:

                  #include <stdio.h>
                  
                  int main() {
                      while (1) {
                          printf("2000
                  ");
                          sleep(1);
                      }
                      return 0;
                  }
                  

                  模拟我将使用的程序,该程序不断地从传感器获取读数.然后我试图用python中的子进程从C程序中读取输出(在本例中为2000"):

                  To simulate the program that I will be using, which takes readings from a sensor constantly. Then I'm trying to read the output (in this case "2000") from the C program with subprocess in python:

                  #!usr/bin/python
                  import subprocess
                  
                  process = subprocess.Popen("./main", stdout=subprocess.PIPE)
                  while True:
                      for line in iter(process.stdout.readline, ''):
                              print line,
                  

                  但这不起作用.从使用打印语句开始,它运行 .Popen 行,然后在 for line in iter(process.stdout.readline, ''): 处等待,直到我按下 Ctrl-C.

                  but this is not working. From using print statements, it runs the .Popen line then waits at for line in iter(process.stdout.readline, ''):, until I press Ctrl-C.

                  这是为什么?这正是我见过的大多数示例的代码,但它不读取文件.

                  Why is this? This is exactly what most examples that I've seen have as their code, and yet it does not read the file.

                  有没有办法让它只在需要阅读的时候运行?

                  Is there a way of making it run only when there is something to be read?

                  推荐答案

                  这是块缓冲问题.

                  以下是我对 Python:从 subprocess.communicate() 读取流式输入 问题.

                  stdio 的程序在终端中交互运行,则通常是行缓冲的,而当它们的标准输出重定向到管道时,它们会被块缓冲.在后一种情况下,在缓冲区溢出或刷新之前,您不会看到新行.

                  stdio-based programs as a rule are line buffered if they are running interactively in a terminal and block buffered when their stdout is redirected to a pipe. In the latter case, you won't see new lines until the buffer overflows or flushed.

                  为避免在每次 printf() 调用后调用 fflush(),您可以在开始时调用 C 程序来强制行缓冲输出:

                  To avoid calling fflush() after each printf() call, you could force line buffered output by calling in a C program at the very beginning:

                  setvbuf(stdout, (char *) NULL, _IOLBF, 0); /* make line buffered stdout */
                  

                  在这种情况下,一旦打印了换行符,缓冲区就会被刷新.

                  As soon as a newline is printed the buffer is flushed in this case.

                  stdbuf 实用程序可以让您在不修改源代码的情况下更改缓冲类型,例如:

                  There is stdbuf utility that allows you to change buffering type without modifying the source code e.g.:

                  from subprocess import Popen, PIPE
                  
                  process = Popen(["stdbuf", "-oL", "./main"], stdout=PIPE, bufsize=1)
                  for line in iter(process.stdout.readline, b''):
                      print line,
                  process.communicate() # close process' stream, wait for it to exit
                  

                  还有其他可用的实用程序,请参阅关闭管道中的缓冲.

                  There are also other utilities available, see Turn off buffering in pipe.

                  要诱使子进程认为它正在交互运行,您可以使用 pexpect 模块 或其类似物,有关使用 pexpectpty 模块的代码示例,请参阅 Python 子进程 readlines() 挂起.这是那里提供的 pty 示例的变体(它应该适用于 Linux):

                  To trick the subprocess into thinking that it is running interactively, you could use pexpect module or its analogs, for code examples that use pexpect and pty modules, see Python subprocess readlines() hangs. Here's a variation on the pty example provided there (it should work on Linux):

                  #!/usr/bin/env python
                  import os
                  import pty
                  import sys
                  from select import select
                  from subprocess import Popen, STDOUT
                  
                  master_fd, slave_fd = pty.openpty()  # provide tty to enable line buffering
                  process = Popen("./main", stdin=slave_fd, stdout=slave_fd, stderr=STDOUT,
                                  bufsize=0, close_fds=True)
                  timeout = .1 # ugly but otherwise `select` blocks on process' exit
                  # code is similar to _copy() from pty.py
                  with os.fdopen(master_fd, 'r+b', 0) as master:
                      input_fds = [master, sys.stdin]
                      while True:
                          fds = select(input_fds, [], [], timeout)[0]
                          if master in fds: # subprocess' output is ready
                              data = os.read(master_fd, 512) # <-- doesn't block, may return less
                              if not data: # EOF
                                  input_fds.remove(master)
                              else:
                                  os.write(sys.stdout.fileno(), data) # copy to our stdout
                          if sys.stdin in fds: # got user input
                              data = os.read(sys.stdin.fileno(), 512)
                              if not data:
                                  input_fds.remove(sys.stdin)
                              else:
                                  master.write(data) # copy it to subprocess' stdin
                          if not fds: # timeout in select()
                              if process.poll() is not None: # subprocess ended
                                  # and no output is buffered <-- timeout + dead subprocess
                                  assert not select([master], [], [], 0)[0] # race is possible
                                  os.close(slave_fd) # subproces don't need it anymore
                                  break
                  rc = process.wait()
                  print("subprocess exited with status %d" % rc)
                  

                  或者通过pexpect

                  使用pty

                  pexpectpty 处理包装到 更高级别的接口:

                  Or use pty via pexpect

                  pexpect wraps pty handling into higher level interface:

                  #!/usr/bin/env python
                  import pexpect
                  
                  child = pexpect.spawn("/.main")
                  for line in child:
                      print line,
                  child.close()
                  

                  问:为什么不直接使用管道 (popen())? 解释了为什么伪 TTY 很有用.

                  Q: Why not just use a pipe (popen())? explains why pseudo-TTY is useful.

                  这篇关于Python C 程序子进程在“for line in iter"处挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Pythonic and efficient way of finding adjacent cells in grid(在网格中查找相邻单元格的 Pythonic 和有效方法)
                  map a hexagonal grid in matplotlib(在 matplotlib 中映射六边形网格)
                  Execute arbitrary python code remotely - can it be done?(远程执行任意 python 代码 - 可以吗?)
                  Python - Plotting colored grid based on values(Python - 根据值绘制彩色网格)
                  Is there a GUI design app for the Tkinter / grid geometry?(是否有 Tkinter/网格几何图形的 GUI 设计应用程序?)
                  tkinter Canvas Scrollbar with Grid?(带有网格的 tkinter 画布滚动条?)
                    <legend id='QzJA7'><style id='QzJA7'><dir id='QzJA7'><q id='QzJA7'></q></dir></style></legend>

                        • <bdo id='QzJA7'></bdo><ul id='QzJA7'></ul>

                            <tbody id='QzJA7'></tbody>

                          <tfoot id='QzJA7'></tfoot>
                          <i id='QzJA7'><tr id='QzJA7'><dt id='QzJA7'><q id='QzJA7'><span id='QzJA7'><b id='QzJA7'><form id='QzJA7'><ins id='QzJA7'></ins><ul id='QzJA7'></ul><sub id='QzJA7'></sub></form><legend id='QzJA7'></legend><bdo id='QzJA7'><pre id='QzJA7'><center id='QzJA7'></center></pre></bdo></b><th id='QzJA7'></th></span></q></dt></tr></i><div id='QzJA7'><tfoot id='QzJA7'></tfoot><dl id='QzJA7'><fieldset id='QzJA7'></fieldset></dl></div>

                          <small id='QzJA7'></small><noframes id='QzJA7'>