18.5.6. サブプロセス—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.6/library/asyncio-subprocess
移動先:案内検索

18.5.6。 サブプロセス

ソースコード: :source: `Lib / asyncio / subprocess.py`

18.5.6.1。 Windowsイベントループ

Windowsでは、デフォルトのイベントループは SelectorEventLoop であり、サブプロセスをサポートしていません。 代わりに ProactorEventLoop を使用する必要があります。 Windowsでの使用例:

import asyncio, sys

if sys.platform == 'win32':
    loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(loop)

18.5.6.2。 サブプロセスを作成する:プロセスを使用した高レベルAPI

AbstractEventLoop.connect_read_pipe()およびAbstractEventLoop.connect_write_pipe()メソッドを使用してパイプを接続します。


18.5.6.3。 サブプロセスを作成します:subprocess.Popenを使用した低レベルAPI

サブプロセスモジュールを使用して、サブプロセスを非同期で実行します。

も参照してください

AbstractEventLoop.connect_read_pipe()およびAbstractEventLoop.connect_write_pipe()メソッド。


18.5.6.4。 定数

asyncio.subprocess.PIPE
[X31X] およびcreate_subprocess_exec()stdinstdout 、または stderr 引数として使用できる特別な値であり、標準ストリームへのパイプを開く必要があります。
asyncio.subprocess.STDOUT
create_subprocess_shell()およびcreate_subprocess_exec()stderr 引数として使用できる特別な値であり、標準エラーが標準出力と同じハンドルに入る必要があることを示します。
asyncio.subprocess.DEVNULL
stdinstdout 、または stderr 引数としてcreate_subprocess_shell()およびcreate_subprocess_exec()に使用できる特別な値であり、特殊ファイル os.devnull が使用されます。


18.5.6.5。 プロセス

class asyncio.subprocess.Process

create_subprocess_exec()またはcreate_subprocess_shell()関数によって作成されたサブプロセス。

Process クラスのAPIは、 subprocess.Popen クラスのAPIに近くなるように設計されていますが、いくつかの違いがあります。

  • 明示的な poll()メソッドはありません

  • communicate()および wait()メソッドは timeout パラメーターを取りません。wait_for()関数を使用してください

  • Universal_newlines パラメーターはサポートされていません(バイト文字列のみがサポートされています)

  • Process クラスのwait()メソッドは非同期ですが、 Popen クラスの wait()メソッドはビジーループとして実装されています。

このクラスはスレッドセーフではありませんサブプロセスとスレッドセクションも参照してください。

send_signal(signal)

シグナル signal を子プロセスに送信します。

ノート

Windowsでは、SIGTERMterminate()のエイリアスです。 CTRL_C_EVENTおよびCTRL_BREAK_EVENTは、CREATE_NEW_PROCESS_GROUPを含む creationflags パラメーターで開始されたプロセスに送信できます。

terminate()

子供を止めなさい。 Posix OSでは、メソッドはsignal.SIGTERMを子に送信します。 Windowsでは、Win32API関数TerminateProcess()が呼び出されて子が停止します。

kill()

子供を殺します。 Posix OSでは、関数はSIGKILLを子に送信します。 Windowsでは、 kill()terminate()のエイリアスです。

stdin

標準入力ストリーム( StreamWriter )、プロセスがstdin=Noneで作成された場合はNone

stdout

標準出力ストリーム( StreamReader )、プロセスがstdout=Noneで作成された場合はNone

stderr

標準エラーストリーム( StreamReader )、プロセスがstderr=Noneで作成された場合はNone

警告

.stdin.write.stdout.read.stderr.read ではなく、communicate()メソッドを使用して、ストリームの一時停止によるデッドロックを回避します。子プロセスの読み取りまたは書き込みとブロック。

pid

プロセスの識別子。

create_subprocess_shell()関数によって作成されたプロセスの場合、この属性は生成されたシェルのプロセス識別子であることに注意してください。

returncode

プロセスが終了したときの戻りコード。 None値は、プロセスがまだ終了していないことを示します。

負の値-Nは、子がシグナルN(Unixのみ)によって終了したことを示します。


18.5.6.6。 サブプロセスとスレッド

asyncioは、異なるスレッドからのサブプロセスの実行をサポートしていますが、制限があります。

  • イベントループはメインスレッドで実行する必要があります
  • 子ウォッチャーは、他のスレッドからサブプロセスを実行する前に、メインスレッドでインスタンス化する必要があります。 メインスレッドでget_child_watcher()関数を呼び出して、子ウォッチャーをインスタンス化します。

asyncio.subprocess.Process クラスはスレッドセーフではありません。

も参照してください

asyncio セクションの同時実行性とマルチスレッド。


18.5.6.7。 サブプロセスの例

18.5.6.7.1。 トランスポートとプロトコルを使用したサブプロセス

サブプロセスの出力を取得し、サブプロセスの終了を待機するために使用するサブプロセスプロトコルの例。 サブプロセスは、AbstractEventLoop.subprocess_exec()メソッドによって作成されます。

import asyncio
import sys

class DateProtocol(asyncio.SubprocessProtocol):
    def __init__(self, exit_future):
        self.exit_future = exit_future
        self.output = bytearray()

    def pipe_data_received(self, fd, data):
        self.output.extend(data)

    def process_exited(self):
        self.exit_future.set_result(True)

@asyncio.coroutine
def get_date(loop):
    code = 'import datetime; print(datetime.datetime.now())'
    exit_future = asyncio.Future(loop=loop)

    # Create the subprocess controlled by the protocol DateProtocol,
    # redirect the standard output into a pipe
    create = loop.subprocess_exec(lambda: DateProtocol(exit_future),
                                  sys.executable, '-c', code,
                                  stdin=None, stderr=None)
    transport, protocol = yield from create

    # Wait for the subprocess exit using the process_exited() method
    # of the protocol
    yield from exit_future

    # Close the stdout pipe
    transport.close()

    # Read the output which was collected by the pipe_data_received()
    # method of the protocol
    data = bytes(protocol.output)
    return data.decode('ascii').rstrip()

if sys.platform == "win32":
    loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(loop)
else:
    loop = asyncio.get_event_loop()

date = loop.run_until_complete(get_date(loop))
print("Current date: %s" % date)
loop.close()

18.5.6.7.2。 ストリームを使用したサブプロセス

Process クラスを使用してサブプロセスを制御し、 StreamReader クラスを使用して標準出力から読み取る例。 サブプロセスは、create_subprocess_exec()関数によって作成されます。

import asyncio.subprocess
import sys

@asyncio.coroutine
def get_date():
    code = 'import datetime; print(datetime.datetime.now())'

    # Create the subprocess, redirect the standard output into a pipe
    create = asyncio.create_subprocess_exec(sys.executable, '-c', code,
                                            stdout=asyncio.subprocess.PIPE)
    proc = yield from create

    # Read one line of output
    data = yield from proc.stdout.readline()
    line = data.decode('ascii').rstrip()

    # Wait for the subprocess exit
    yield from proc.wait()
    return line

if sys.platform == "win32":
    loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(loop)
else:
    loop = asyncio.get_event_loop()

date = loop.run_until_complete(get_date())
print("Current date: %s" % date)
loop.close()