>  기사  >  백엔드 개발  >  비차단 하위 프로세스에서 명령을 비동기적으로 실행하는 Python의 방법은 무엇입니까

비차단 하위 프로세스에서 명령을 비동기적으로 실행하는 Python의 방법은 무엇입니까

WBOY
WBOY앞으로
2023-06-02 18:51:241406검색

1. asyncio.subprocess.Process란 무엇인가요?

asyncio에서 명령을 실행할 수 있습니다. 이 명령은 읽기 및 쓰기 작업에 비차단 I/O를 사용하도록 허용된 하위 프로세스에서 실행됩니다.

asyncio 모듈의 하위 프로세스 모듈은 asyncio가 실행하는 하위 프로세스를 나타내는 Process 클래스를 제공합니다. asyncio 프로그램에서는 자식 프로세스에 대한 핸들을 제공하여 대기 및 종료와 같은 작업을 수행할 수 있도록 합니다.

API는 multiprocessing.Process 클래스와 매우 유사하며 아마도 subprocess.Popen 클래스와 더 유사할 것입니다. 특히 wait(), communications(), send_signal() 등의 메서드와 stdin, stdout, stderr 등의 속성을 subprocess.Popen과 공유합니다.

이제 asyncio.subprocess.Process 클래스가 무엇인지 알았으니, 이를 asyncio 프로그램에서 어떻게 사용하는지 살펴보겠습니다.

asyncio.subprocess.Process 인스턴스를 직접 생성하지 않습니다. 대조적으로, asyncio 프로그램에서 하위 프로세스를 실행하면 클래스 인스턴스가 자동으로 생성됩니다.

외부 프로그램을 하위 프로세스로 실행하고 프로세스 인스턴스를 얻는 방법에는 두 가지가 있습니다.

  • asyncio.create_subprocess_exec()는 명령을 직접 실행하는 데 사용됩니다.

  • 쉘을 사용하여 명령을 실행하려면 asyncio.create_subprocess_shell() 함수를 사용하세요.

각 예를 차례로 살펴보겠습니다.

2. 명령을 직접 실행하는 방법

명령은 명령줄(터미널 또는 명령 프롬프트)에서 실행되는 프로그램입니다. 이것은 직접 실행되는 또 다른 프로그램입니다.

Linux 및 macOS의 일반적인 예는 다음과 같습니다.

  • ‘ls’ 디렉토리 내용 나열

  • ‘cat’ 파일 내용 보고

  • "데이터" 보고 날짜

  • ‘echo’ 문자열 보고

  • ‘sleep’ 몇 초간 절전 모드

create_subprocess_exec() 함수를 사용하면 asyncio 프로그램에서 명령을 실행할 수 있습니다.

asyncio.create_subprocess_exec() 함수는 명령을 받아 직접 실행합니다.

이는 명령이 하위 프로세스에서 실행될 수 있도록 하고 asyncio 코루틴이 이를 읽고 쓰고 기다릴 수 있도록 허용하기 때문에 유용합니다.

asyncio.create_subprocess_shell() 함수와 달리 asyncio.create_subprocess_exec()는 명령을 실행하기 위해 셸을 사용하지 않습니다.

이는 명령 실행 시 셸 변수, 스크립트, 와일드카드 등 셸에서 제공하는 기능을 사용할 수 없음을 의미합니다.

이는 또한 쉘 주입 기회가 없으므로 명령을 실행하는 것이 더 안전할 수 있음을 의미합니다.

이제 asyncio.create_subprocess_exec()가 무엇을 하는지 알았으니, 어떻게 사용하는지 살펴보겠습니다.

2.1. Asyncio create_subprocess_exec() 사용 방법

asyncio.create_subprocess_exec() 함수는 하위 프로세스에서 주어진 문자열 명령을 실행합니다.

하위 프로세스를 나타내는 asyncio.subprocess.Process 객체를 반환합니다.

create_subprocess_exec() 함수는 코루틴이므로 기다려야 합니다. 하위 프로세스가 완료된 때가 아니라 하위 프로세스가 시작된 후에 반환됩니다.

...
# execute a command in a subprocess
process = await asyncio.create_subprocess_exec('ls')

create_subprocess_exec() 함수를 사용할 때 명령에 대한 인수는 후속 인수로 제공되어야 합니다.

...
# execute a command with arguments in a subprocess
process = await asyncio.create_subprocess_exec('ls', '-l')

wait() 메소드를 기다려 하위 프로세스가 완료될 때까지 기다릴 수 있습니다.

...
# wait for the subprocess to terminate
await process.wait()

terminate() 또는 kill() 메서드를 호출하여 하위 프로세스를 직접 중지할 수 있으며, 이는 하위 프로세스에서 신호를 발생시킵니다.

...
# terminate the subprocess
process.terminate()

표준 입력, 출력 및 오류는 stdin, stderr 및 stdout을 통해 처리됩니다. asyncio 프로그램이 하위 프로세스의 입력 또는 출력을 처리하도록 할 수 있습니다.

이는 입력 또는 출력 스트림을 지정하고 asyncio.subprocess.PIPE와 같이 리디렉션할 상수를 지정하여 달성할 수 있습니다.

예를 들어, 명령 출력을 asyncio 프로그램으로 리디렉션할 수 있습니다:

...
# start a subprocess and redirect output
process = await asyncio.create_subprocess_exec('ls', stdout=asyncio.subprocess.PIPE)

그런 다음 asyncio.subprocess.Process 인스턴스를 통해 communications() 메서드를 통해 프로그램의 출력을 읽을 수 있습니다.

이 메서드는 코루틴이므로 기다려야 합니다. 하위 프로세스를 통해 데이터를 보내고 받는 데 사용됩니다.

...
# read data from the subprocess
line = process.communicate()

"input" 매개변수를 바이트 단위로 설정하여 communications() 메소드를 통해 하위 프로세스에 데이터를 보낼 수도 있습니다.

...
# start a subprocess and redirect input
process = await asyncio.create_subprocess_exec('ls', stdin=asyncio.subprocess.PIPE)
# send data to the subprocess
process.communicate(input=b'Hello\n')

내부적으로 asyncio.subprocess.PIPE는 하위 프로세스와 데이터를 보내기 위해 StreamReader 또는 StreamWriter를 가리키도록 하위 프로세스를 구성하고, communications() 메서드는 구성된 판독기 또는 쓰기 바이트에서 읽습니다.

stdin, stdout 및 stderr 속성을 통한 하위 프로세스를 통해 StreamReader 또는 StreamWriter와 직접 상호 작용할 수 있습니다.

...
# read a line from the subprocess output stream
line = await process.stdout.readline()

이제 사용법을 이해했으니 create_subprocess_exec() 함수를 사용하는 몇 가지 실제 예제를 살펴보겠습니다.

2.2.Asyncio create_subprocess_exec() 예제

asyncio의 하위 프로세스에서 명령을 실행하는 방법을 알아볼 수 있습니다. 이 예에서는 "echo" 명령을 실행하여 문자열을 보고합니다.

echo 명령은 제공된 문자열을 표준 출력에 직접 보고합니다. 전체 예가 아래에 나열되어 있습니다.

이 예에서는 "echo" 명령에 액세스할 수 있다고 가정합니다. Windows에서 작동할지는 잘 모르겠습니다.

# SuperFastPython.com
# example of executing a command as a subprocess with asyncio
import asyncio
 
# main coroutine
async def main():
    # start executing a command in a subprocess
    process = await asyncio.create_subprocess_exec('echo', 'Hello World')
    # report the details of the subprocess
    print(f'subprocess: {process}')
 
# entry point
asyncio.run(main())

运行示例首先创建 main() 协程并将其作为 asyncio 程序的入口点执行。

main() 协程运行并调用 create_subprocess_exec() 函数来执行命令。

main() 协程在创建子进程时挂起。返回一个 Process 实例。

main() 协程恢复并报告子进程的详细信息。 main() 进程终止,asyncio 程序终止。

echo 命令的输出在命令行上报告。这突出了我们如何从 asyncio 程序执行命令。

Hello World
subprocess: <Process 50249>

3. 如何通过 Shell 运行命令

我们可以使用 shell 执行命令。称为命令行解释器 (CLI),shell 是用来操作命令行界面的用户界面。它将代表用户解释和执行命令。

它还提供诸如用于脚本、通配符、管道、shell 变量(例如 PATH)等的原始编程语言等功能。

例如,我们可以将一条命令的输出重定向为另一条命令的输入,比如将“/etc/services”文件的内容重定向到word count命令“wc”中,统计行数:

cat /etc/services | wc -l

基于 Unix 的操作系统中的 shell 示例包括:

비차단 하위 프로세스에서 명령을 비동기적으로 실행하는 Python의 방법은 무엇입니까

shell 已经在运行,它被用来启动 Python 程序。您无需执行任何特殊操作即可获取或访问 shell。

我们可以通过 create_subprocess_shell() 函数从 asyncio 程序执行命令。

asyncio.create_subprocess_shell() 函数接受一个命令并使用当前用户 shell 执行它。

这很有用,因为它不仅允许执行命令,还允许使用 shell 的功能,例如重定向、通配符等。

该命令将在执行 asyncio 程序的进程的子进程中执行。重要的是,asyncio 程序能够与子进程异步交互,例如通过协程。

通过 shell 而不是直接执行命令时,可能会有安全考虑。

这是因为请求执行命令和正在执行的命令之间至少存在一层间接和解释,允许可能的恶意注入。

现在我们知道了 asyncio.create_subprocess_shell() 的作用,让我们看看如何使用它。

3.1. 如何使用 Asyncio create_subprocess_shell()

asyncio.create_subprocess_shell() 函数将通过当前 shell 执行给定的字符串命令。

它返回一个表示进程的 asyncio.subprocess.Process 对象。

它和上一节中介绍的 create_subprocess_shell() 函数非常类似。不过,我们将回顾如何使用该函数以及如何通过 Process 实例与流程交互(以防您直接跳到本节)。

我们需要等待create_subprocess_shell()函数完成,因为它是一个协程。它会在子流程启动后返回,而不是在子流程完成时返回。

...
# start a subprocess
process = await asyncio.create_subprocess_shell(&#39;ls&#39;)

我们可以通过等待 wait() 方法来等待子进程完成。

...
# wait for the subprocess to terminate
await process.wait()

我们可以通过调用 terminate() 或 kill() 方法直接停止子进程,这将在子进程中引发一个信号。

命令的输入和输出将由 shell 处理,例如标准输入、标准错误和标准输出。

我们可以让 asyncio 程序处理子进程的输入或输出。

这可以通过指定输入或输出流并指定要重定向的常量来实现,例如 asyncio.subprocess.PIPE。

例如,我们可以将命令的输出重定向到 asyncio 程序:

...
# start a subprocess and redirect output
process = await asyncio.create_subprocess_shell(&#39;ls&#39;, stdout=asyncio.subprocess.PIPE)

然后我们可以通过 asyncio.subprocess.Process 实例通过 communicate() 方法读取程序的输出。

此方法是协程,必须等待。它用于通过子流程发送和接收数据。

...
# read data from the subprocess
line = process.communicate()

我们还可以通过以字节为单位设置“input”参数,通过 communicate() 方法将数据发送到子进程。

...
# start a subprocess and redirect input
process = await asyncio.create_subprocess_shell(&#39;ls&#39;, stdin=asyncio.subprocess.PIPE)
# send data to the subprocess
process.communicate(input=b&#39;Hello\n&#39;)

在后台,asyncio.subprocess.PIPE 将子进程配置为指向 StreamReader 或 StreamWriter,用于向子进程发送数据或从子进程发送数据,并且 communicate() 方法将从配置的读取器读取或写入字节。

我们可以通过子进程通过 stdin、stdout 和 stderr 属性直接与 StreamReader 或 StreamWriter 交互。

...
# read a line from the subprocess output stream
line = await process.stdout.readline()

现在我们已经掌握了如何使用 create_subprocess_shell() 函数,接下来让我们查看一些实际工作示例。

3.2. Asyncio create_subprocess_shell() 示例

我们可以尝试用 shell 在 asyncio 的子进程中执行指令。在这个例子中,我们将执行“echo”命令来报告一个字符串。

echo 命令将直接在标准输出上报告提供的字符串。下面列出了完整的示例。

请注意,此示例假设您可以访问“echo”命令,我不确定它是否适用于 Windows。

# SuperFastPython.com
# example of executing a shell command as a subprocess with asyncio
import asyncio
 
# main coroutine
async def main():
    # start executing a shell command in a subprocess
    process = await asyncio.create_subprocess_shell(&#39;echo Hello World&#39;)
    # report the details of the subprocess
    print(f&#39;subprocess: {process}&#39;)
 
# entry point
asyncio.run(main())

首先创建 main() 协程并将其作为入口点运行的是 asyncio 程序的示例。在 main() 协程中,通过调用 create_subprocess_shell() 函数来执行命令。

main() 协程在运行时调用 create_subprocess_shell() 函数来执行命令。main() 协程恢复并报告子进程的详细信息。 main() 进程终止,asyncio 程序终止。

echo 命令的输出在命令行上报告。这个例子清晰地展示了我们如何利用 shell 从 asyncio 程序中运行命令。

subprocess: <Process 43916>
Hello World

위 내용은 비차단 하위 프로세스에서 명령을 비동기적으로 실행하는 Python의 방법은 무엇입니까의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제