A 和 B 两个 python 脚本存在兼容性问题,需要单独的 conda 环境。这是场景。当脚本 A 运行时,它向进程 B 发送数据(脚本 B 在不同的终端中运行),进程 B 将输出返回给进程 A(进程 A 无法进入休眠状态)。我一直在使用 pickle 文件在这两个进程之间交换数据,但这种方法似乎很慢,我想加快速度,这对我的工作是必要的。
io.TextIOWrapper
中将使通信更容易,就像使用套接字一样简单)你可以使用parent.py,调用child.sh来设置conda环境,然后调用child.py 例如使用 zmq 进行通信(下面的辅助模块)
**父母.py
import numpy as np
from subprocess import call
from communicator import EZZMQ
# set up the communicator
zmq_port, send, recv = EZZMQ(None)
# call child with port info
call(f'./child.sh {zmq_port}', shell=True)
def child_process(data):
send(data) # send
# something done by child
return recv() #receive
# create data
data = np.random.random((3,3))
transformed_data = child_process(data)
print('data', data)
print('transformed data', transformed_data)
child.sh:
# !/bin/bash
# set up environment variables and conda
source $HOME/git/lcls2/setup_env.sh
# echo "using port: $1"
python child.py $1 &
child.py
import numpy as np
import sys
from communicator import EZZMQ
# get the port info
zmq_port = sys.argv[1]
#bind the port
zmq_port, send, recv = EZZMQ(zmq_port)
# get the data
data = recv()
# transform
data=data+1
# send back
data = send(data)
和一个助手“communicator.py”模块
import zmq
import zlib, pickle
port_selected = None
def EZZMQ(port): # None will start the parent
context = zmq.Context()
zmq_socket = context.socket(zmq.PAIR)
if type(port)==type(None): # parent to select the port
port_selected = zmq_socket.bind_to_random_port('tcp://*', min_port=50000, max_port=65004, max_tries=1000)
else: # child is given the port
zmq_socket.connect("tcp://localhost:%s" % port)
port_selected = int(port)
def send(obj, flags=0, protocol=-1):
"""pickle an object, and zip the pickle before sending it"""
p = pickle.dumps(obj, protocol)
z = zlib.compress(p)
return zmq_socket.send(z, flags=flags)
def recv(flags=0, protocol=-1):
"""inverse of send_zipped_pickle"""
z = zmq_socket.recv(flags)
p = zlib.decompress(z)
return pickle.loads(p)
return port_selected, send, recv