第十章:使用进程、线程和协程提供并发性-asyncio:异步I/O、事件循环和并发工具-使用子进程-向子进程发送数据

10.5.12.3 向子进程发送数据
前面的两个例子只使用了一个通信通道从第二个进程读取数据。通常有必要把数据发送给一个命令来处理。下面的例子定义了一个协程来执行UNIX命令tr,转换其输入流中的字符。在这里,tr用来把小写字母转换为大写字母。
to_upper()协程接收一个事件循环和一个输入串作为参数。它会创建另一个进程运行"tr [:lower:] [:upper:]"。

import asyncio
import asyncio.subprocess

async def to_upper(input):
    print('in to_upper')

    create = asyncio.create_subprocess_exec(
        'tr','[:lower:]','[:upper:]',
        stdout=asyncio.subprocess.PIPE,
        stdin=asyncio.subprocess.PIPE,
        )
    print('launching process')
    proc = await create
    print('pid {}'.format(proc.pid))

# 接下来,to_upper()使用Process的communicate()方法将输入串发送到这个命令,并异步
# 地读取得到的所有输出。与subprocess.Popen中的相应方法一样,communicate()会返回
# 这个方法输出的所有字节串。如果一个命令有可能生成太多的数据(在内存中放不下),
# 那么不能一次生成全部输入,或者必须增量地处理输出,一种更好的方法是直接使用
# Process的stdin,stdout和stderr句柄而不是调用communicate()。
    print('communicating with process')
    stdout,stderr = await proc.communicate(input.encode())
    # I/O完成后,要等待进程完全退出,确保他得到适当的清理。
    print('waiting for process tp complete')
    await proc.wait()
    # 然后可以检查返回码,并解码输出字节串以准备协程的返回值。
    return_code = proc.returncode
    print('return_code {}'.format(return_code))
    if not return_code:
        results = bytes(stdout).decode()
    else:
        results = ''
    return (return_code,results)

# 程序的主要比分建立了一个要转换的消息中,并建立事件循环来运行to_upper(),然后
# 输出结果。
MESSAGE = """
THis message will be converted
to all caps.
"""

event_loop = asyncio.get_event_loop()
try:
    return_code,results = event_loop.run_until_complete(
        to_upper(MESSAGE)
        )
finally:
    event_loop.close()

if return_code:
    print('error exit {}'.format(return_code))
else:
    print('Original:{!r}'.format(MESSAGE))
    print('Changed :{!r}'.format(results))

输出显示了操作序列以及这个简单文本消息的转换结果。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值