Python 异步并联发电机
我有一个python脚本,它懒洋洋地收集数据,创建训练样本,并将其传递给我的ML模型进行学习。目前,我正在使用标准python生成器生成数据,据我所知,它是同步的。我正在寻找一种智能、干净的方法,使我的生成器真正异步,因此当我使用它作为迭代器时,在我取出最后一个样本后,下一个数据样本的处理将立即开始。考虑下面的例子:Python 异步并联发电机,python,python-3.x,asynchronous,parallel-processing,async-await,Python,Python 3.x,Asynchronous,Parallel Processing,Async Await,我有一个python脚本,它懒洋洋地收集数据,创建训练样本,并将其传递给我的ML模型进行学习。目前,我正在使用标准python生成器生成数据,据我所知,它是同步的。我正在寻找一种智能、干净的方法,使我的生成器真正异步,因此当我使用它作为迭代器时,在我取出最后一个样本后,下一个数据样本的处理将立即开始。考虑下面的例子: def asyncgen(): for i in range(5): print("I want this part to work asynchronou
def asyncgen():
for i in range(5):
print("I want this part to work asynchronously :(")
i = 0;
while(i<1e8):
i+=1
yield "Hi"
a = asyncgen()
for w in a:
print(w)
i = 0
while (i < 1e8):
i += 1
我如何使我的生成器在收到Hi后立即在不同的进程下开始异步处理内容?当前,处理仅在for循环调用next之后开始
我一直在研究政治公众人物525,但他们似乎只是同时工作,而不是并行该死的吉尔!。在Python中,这是一种很好的、最好是本机的方法。绕过GIL的唯一方法是使用
因此,在上面的代码中,asyncgen作为并行进程独立运行了5次。然后在程序结束前将它们连接起来。保持一个列表p只是一个说明。套接字也是解决这个问题的一个很好的方法。 基本上,与其让一个程序带有线程或多个进程,不如让一个外部程序执行您从外部连接到的异步程序 了解有关套接字的更多信息,请访问 下面是一个非常完整的python 2.7示例:
import argparse
import logging
import socket
import time
import random
description = """
This program sends data across a socket
"""
arg_parser = argparse.ArgumentParser(description=description)
arg_parser.add_argument('--AgentIP', '-i', action='store'
, default='localhost' , type=str
, help="The IP address of this Server that client will connect to."
)
arg_parser.add_argument('--AgentPort', '-p', action='store'
, default='13000' , type=int
, help="The port number of the socket that client will connect to."
)
arg_parser.add_argument('--log', action='store'
, default='INFO' , type=str
, help="Log level"
, choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
)
args = arg_parser.parse_args()
# use Logger for great justice and heavenly output
logging.basicConfig(level=getattr(logging, args.log, 'CRITICAL'))
log = logging.getLogger(name='SERVER')
### vvv YOUR CODE vvv ###
def asyncgen(log):
for i in range(5):
log.debug("I want this part to work asynchronously :(")
time.sleep(random.random())
yield "Hi"
### ^^^ YOUR CODE ^^^ ###
def make_a_connection(server, log):
# Accept outside connections
(client_socket, address) = server.accept()
log.info("Got a connection : {}:{}".format(client_socket,address))
for value in asyncgen(log):
client_socket.send(value)
log.info("SEND:{}".format(value))
client_socket.close()
def main(args, log):
server = socket.socket( socket.AF_INET , socket.SOCK_STREAM )
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
hostname = socket.gethostbyname(args.AgentIP)
port = args.AgentPort
address = (hostname, port)
server.bind(address)
server.listen(1)
log.info("Server started on {}:{}".format(hostname, port))
try:
while True:
make_a_connection(server, log)
except (KeyboardInterrupt, SystemExit):
server.close()
log.info("Server connections closed")
if __name__=='__main__':
main(args, log)
你读过吗?@lalengua是的,我读过类似的博客和文档。线程、greenlet和asyncio都在单个进程上运行。虽然我的解析前端正在做一些io的事情,但它也在做很多处理,我不想在同一个过程中减慢我的计算速度。我的机器上有足够的内核来并行运行。我知道这个选项,我只是希望有更干净的东西:。。。所以我想我将要编写一个包装类,它是iterable,接收生成器并提前调用几个项,将它们准备到队列中,并在调用其uu next uu_u方法时逐个生成它们,而一些后台工作人员将在需要时填充队列。很遗憾,无法从多处理中逃脱。发电机看起来很优雅,请使用netcat查看此运行情况。请尝试nc localhost 13000
import argparse
import logging
import socket
import time
import random
description = """
This program sends data across a socket
"""
arg_parser = argparse.ArgumentParser(description=description)
arg_parser.add_argument('--AgentIP', '-i', action='store'
, default='localhost' , type=str
, help="The IP address of this Server that client will connect to."
)
arg_parser.add_argument('--AgentPort', '-p', action='store'
, default='13000' , type=int
, help="The port number of the socket that client will connect to."
)
arg_parser.add_argument('--log', action='store'
, default='INFO' , type=str
, help="Log level"
, choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
)
args = arg_parser.parse_args()
# use Logger for great justice and heavenly output
logging.basicConfig(level=getattr(logging, args.log, 'CRITICAL'))
log = logging.getLogger(name='SERVER')
### vvv YOUR CODE vvv ###
def asyncgen(log):
for i in range(5):
log.debug("I want this part to work asynchronously :(")
time.sleep(random.random())
yield "Hi"
### ^^^ YOUR CODE ^^^ ###
def make_a_connection(server, log):
# Accept outside connections
(client_socket, address) = server.accept()
log.info("Got a connection : {}:{}".format(client_socket,address))
for value in asyncgen(log):
client_socket.send(value)
log.info("SEND:{}".format(value))
client_socket.close()
def main(args, log):
server = socket.socket( socket.AF_INET , socket.SOCK_STREAM )
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
hostname = socket.gethostbyname(args.AgentIP)
port = args.AgentPort
address = (hostname, port)
server.bind(address)
server.listen(1)
log.info("Server started on {}:{}".format(hostname, port))
try:
while True:
make_a_connection(server, log)
except (KeyboardInterrupt, SystemExit):
server.close()
log.info("Server connections closed")
if __name__=='__main__':
main(args, log)