12

http://docs.python.org/library/pty.htmlは言う -

pty.fork()¶ フォーク。子の制御端末を疑似端末に接続します。戻り値は (pid, fd) です。子は pid 0 を取得し、fd は無効であることに注意してください。親の戻り値は子の pid であり、fd は子の制御端末 (および子の標準入出力) に接続されたファイル記述子です。

これはどういう意味ですか? すべてのプロセスには 3 つの fd (stdin、stdout、stderr) があります。これは現在、これらの fd に影響しますか? 子プロセスにはこれらの fd がありませんか? 私は混乱しています.--完全に。

4

5 に答える 5

19

私はついにpty.forkPythonで最小限の例を手に入れたと思います.同様の例を見つけるのは非常に難しいことがわかったので、@joniの回答の実例としてここに投稿しています. それは基本的に以下に基づいています。

特に厄介な点master_open()は、古いドキュメントをまだ参照しているドキュメントを見つけることです。そして、ファイル記述子 ( fork メソッドによって返される) が親プロセスによって読み取られない限り、子プロセスを生成しpty.forkないという事実! (そのような要件がないことに注意してください)また、移植性が少し高いようです(一部のプラットフォームでは機能しないことに注意してください)。os.forkos.forkpty.fork

とにかく、最初にpyecho.py、実行可能ファイルとして機能するスクリプト ( ) を示します (標準入力から行を読み取り、大文字で書き戻すだけです)。

#!/usr/bin/env python
# pyecho.py

import sys;

print "pyecho starting..."

while True:
  print sys.stdin.readline().upper()

...そして、これが実際のスクリプトです(pyecho.pyが同じディレクトリにある必要があります):

#!/usr/bin/env python

import sys
import os
import time
import pty

def my_pty_fork():

  # fork this script
  try:
    ( child_pid, fd ) = pty.fork()    # OK
    #~ child_pid, fd = os.forkpty()      # OK
  except OSError as e:
    print str(e)

  #~ print "%d - %d" % (fd, child_pid)
  # NOTE - unlike OS fork; in pty fork we MUST use the fd variable
  #   somewhere (i.e. in parent process; it does not exist for child)
  # ... actually, we must READ from fd in parent process...
  #   if we don't - child process will never be spawned!

  if child_pid == 0:
    print "In Child Process: PID# %s" % os.getpid()
    # note: fd for child is invalid (-1) for pty fork!
    #~ print "%d - %d" % (fd, child_pid)

    # the os.exec replaces the child process
    sys.stdout.flush()
    try:
      #Note: "the first of these arguments is passed to the new program as its own name"
      # so:: "python": actual executable; "ThePythonProgram": name of executable in process list (`ps axf`); "pyecho.py": first argument to executable..
      os.execlp("python","ThePythonProgram","pyecho.py")
    except:
      print "Cannot spawn execlp..."
  else:
    print "In Parent Process: PID# %s" % os.getpid()
    # MUST read from fd; else no spawn of child!
    print os.read(fd, 100) # in fact, this line prints out the "In Child Process..." sentence above!

    os.write(fd,"message one\n")
    print os.read(fd, 100)        # message one
    time.sleep(2)
    os.write(fd,"message two\n")
    print os.read(fd, 10000)      # pyecho starting...\n MESSAGE ONE
    time.sleep(2)
    print os.read(fd, 10000)      # message two \n MESSAGE TWO
    # uncomment to lock (can exit with Ctrl-C)
    #~ while True:
      #~ print os.read(fd, 10000)


if __name__ == "__main__":
    my_pty_fork()

さて、これが誰かに役立つことを願っています、
乾杯!

于 2011-08-05T08:39:51.193 に答える
5

pty.fork() を使用する主なポイントは、返された疑似端末 (pty) ファイル記述子を使用して、生成されたプロセスと別の方法で通信できることです。stdin/out/err ではなく、(疑似) 端末への直接の書き込みと読み取りを介して。

pty と tty に関する詳細情報(StackOverflow から) と、 pty.fork() を使用した簡単な例へのリンクもあります。

于 2013-10-29T08:01:26.577 に答える
3

「そしてfdは子の制御端末に接続されたファイル記述子です」->子プロセスは違いを認識せず、通常どおりstdin/outにアクセスできます(stderrについては知りません)。唯一の違いは、「パイプ」の反対側には、ユーザーが読み取り/入力している端末ではなく、アクセスできる親プロセスが返された fd によるものであることです。

于 2010-10-26T10:15:26.283 に答える
0

ありがとう Joni.Here は私が理解したものです。親プロセスは ptmx マスターに接続されています。親は、キーボードからの入力またはマスターからのデータを待ちます。

子はその stdin、stdout、および stderr を閉じます。また、スレーブ stdin、stdout.stderr を複製します。1+1 と入力すると、プログラムは入力を待っています (子とスレーブの両方に stdin、stdout、stderr があることを思い出してください)。マスターはその答え「2」を計算し、stdout に書き込みます。親はマスターからのデータを待っているため、「2」を取得して stdout に書き込みます。

疑似端末で古き良きCプログラムをいくつか試した後、この結論に達しました:) Pythonのロジックはそれらと変わらないと思います。HTH誰か。

于 2010-10-27T06:34:48.040 に答える