python 将长 运行 进程传递给另一个脚本
python pass long running process to another script
我正在尝试 运行 两个 python 脚本,script1 调用 script2,script2 是一个很长的 运行ning 进程,它会实时将内容传回给 script1。
这是脚本 1:
from script2 import Test2
model_info = Test2()
info = model_info.test2_run()
print info
这是脚本2:
class Test2:
def __init__(self):
print("running")
def test2_run(self):
a = 100000
for line in range(a):
return line
我如何让 script2 不断地将 line
反馈给 script1?
下面给出了实现此目的的四种不同方法。假设您有两个 python 脚本,producer.py
和 consumer.py
,如下所示。
producer.py
import multiprocessing
import threading
range_limit = 3
class LineProducer(object):
def __init__(self, msg = ''):
print(self.prepare_line('Initializing %s%s' % (self.__class__.__name__, msg)))
def prepare_line(self, line):
return '%d - %d : %s' % (multiprocessing.current_process().pid, threading.current_thread().ident, line)
def run(self):
for line in range(range_limit):
yield self.prepare_line(line)
class MultiThreadedLineProducer(LineProducer):
def produce(self, q):
for line in range(range_limit):
q.put(self.prepare_line(line))
q.put(None)
def run(self):
q = multiprocessing.Queue()
threading.Thread(target = self.produce, args = (q,)).start()
while 1:
line = q.get(True)
if line == None:
break;
yield line
class MultiProcessedLineProducer(LineProducer):
def produce(self, q):
for line in range(range_limit):
q.put(self.prepare_line(line))
q.put(None)
def run(self):
q = multiprocessing.Queue()
multiprocessing.Process(target = self.produce, args=(q,)).start()
while 1:
line = q.get(True)
if line == None:
break;
yield line
if __name__ == '__main__':
for line in LineProducer(' inside a separate process').run():
print(line)
consumer.py
import sys
from subprocess import Popen, PIPE, STDOUT
from producer import LineProducer, MultiThreadedLineProducer, MultiProcessedLineProducer
#using normal yield
for line in LineProducer().run():
sys.stdout.write(line + '\n')
#using yield with multi threading
for line in MultiThreadedLineProducer().run():
sys.stdout.write(line + '\n')
#using yield with mult processing
for line in MultiProcessedLineProducer().run():
sys.stdout.write(line + '\n')
#using normal yield in child process
for line in Popen(['python', 'producer.py'], bufsize = 0, shell = False, stdout = PIPE, stderr = STDOUT).stdout:
sys.stdout.write(line)
现在,如果您执行 python consumer.py
,它将产生类似于下面给出的输出
8834 - 140419442169664 : Initializing LineProducer
8834 - 140419442169664 : 0
8834 - 140419442169664 : 1
8834 - 140419442169664 : 2
8834 - 140419442169664 : Initializing MultiThreadedLineProducer
8834 - 140419409151744 : 0
8834 - 140419409151744 : 1
8834 - 140419409151744 : 2
8834 - 140419442169664 : Initializing MultiProcessedLineProducer
8837 - 140419442169664 : 0
8837 - 140419442169664 : 1
8837 - 140419442169664 : 2
8839 - 140280258066240 : Initializing LineProducer inside a separate process
8839 - 140280258066240 : 0
8839 - 140280258066240 : 1
8839 - 140280258066240 : 2
输出格式为 PID - ThreadID : Message
,其中 PID
是进程 ID,ThreadID
是生成 Message
的线程标识符。
现在您可以看到,第一组输出的 PID 和 ThreadID 对于所有行都是相同的。这里的供应是基于需求的,即当消费者要求时生产输出线。
在第二组中,PID 保持不变,但生成的行具有不同的 ThreadID。那是因为,生产者和消费者 运行 在不同的线程中。而且生产线的生产不考虑消费者的需求。 Python 中的线程使用原生线程,如 pthread,但由于全局解释器锁,没有两个线程可以同时 运行,这意味着您不会获得真正意义上的并行性。
现在,来到第三组,PID 不同,这意味着消费者 运行 处于从当前进程派生的不同进程中。这实现了真正的并行性,并且可以有效地利用多个 CPU 核心。与多线程一样,无论消费者需求如何,这都会产生生产线。
多线程和多处理使用队列在threads/processes之间进行通信。您可以在创建队列时通过指定项目数来限制生产线的生产。以这种方式,生成行直到队列变满。随着队列中的行被消耗,生产恢复。
现在,最后一组,它使用fork/exec机制来创建一个进程并用指定的可执行文件替换图像。它与第一组相同,但具有不同的 PID 和 ThreadID。这种方式与第三种方式的区别在于进程之间不能使用队列进行通信,而是依赖于管道等IPC机制。此外,producer.py
应该是一个可执行的 python 脚本。在这种情况下,也不管消费者的需求而生产生产线。
我正在尝试 运行 两个 python 脚本,script1 调用 script2,script2 是一个很长的 运行ning 进程,它会实时将内容传回给 script1。
这是脚本 1:
from script2 import Test2
model_info = Test2()
info = model_info.test2_run()
print info
这是脚本2:
class Test2:
def __init__(self):
print("running")
def test2_run(self):
a = 100000
for line in range(a):
return line
我如何让 script2 不断地将 line
反馈给 script1?
下面给出了实现此目的的四种不同方法。假设您有两个 python 脚本,producer.py
和 consumer.py
,如下所示。
producer.py
import multiprocessing
import threading
range_limit = 3
class LineProducer(object):
def __init__(self, msg = ''):
print(self.prepare_line('Initializing %s%s' % (self.__class__.__name__, msg)))
def prepare_line(self, line):
return '%d - %d : %s' % (multiprocessing.current_process().pid, threading.current_thread().ident, line)
def run(self):
for line in range(range_limit):
yield self.prepare_line(line)
class MultiThreadedLineProducer(LineProducer):
def produce(self, q):
for line in range(range_limit):
q.put(self.prepare_line(line))
q.put(None)
def run(self):
q = multiprocessing.Queue()
threading.Thread(target = self.produce, args = (q,)).start()
while 1:
line = q.get(True)
if line == None:
break;
yield line
class MultiProcessedLineProducer(LineProducer):
def produce(self, q):
for line in range(range_limit):
q.put(self.prepare_line(line))
q.put(None)
def run(self):
q = multiprocessing.Queue()
multiprocessing.Process(target = self.produce, args=(q,)).start()
while 1:
line = q.get(True)
if line == None:
break;
yield line
if __name__ == '__main__':
for line in LineProducer(' inside a separate process').run():
print(line)
consumer.py
import sys
from subprocess import Popen, PIPE, STDOUT
from producer import LineProducer, MultiThreadedLineProducer, MultiProcessedLineProducer
#using normal yield
for line in LineProducer().run():
sys.stdout.write(line + '\n')
#using yield with multi threading
for line in MultiThreadedLineProducer().run():
sys.stdout.write(line + '\n')
#using yield with mult processing
for line in MultiProcessedLineProducer().run():
sys.stdout.write(line + '\n')
#using normal yield in child process
for line in Popen(['python', 'producer.py'], bufsize = 0, shell = False, stdout = PIPE, stderr = STDOUT).stdout:
sys.stdout.write(line)
现在,如果您执行 python consumer.py
,它将产生类似于下面给出的输出
8834 - 140419442169664 : Initializing LineProducer
8834 - 140419442169664 : 0
8834 - 140419442169664 : 1
8834 - 140419442169664 : 2
8834 - 140419442169664 : Initializing MultiThreadedLineProducer
8834 - 140419409151744 : 0
8834 - 140419409151744 : 1
8834 - 140419409151744 : 2
8834 - 140419442169664 : Initializing MultiProcessedLineProducer
8837 - 140419442169664 : 0
8837 - 140419442169664 : 1
8837 - 140419442169664 : 2
8839 - 140280258066240 : Initializing LineProducer inside a separate process
8839 - 140280258066240 : 0
8839 - 140280258066240 : 1
8839 - 140280258066240 : 2
输出格式为 PID - ThreadID : Message
,其中 PID
是进程 ID,ThreadID
是生成 Message
的线程标识符。
现在您可以看到,第一组输出的 PID 和 ThreadID 对于所有行都是相同的。这里的供应是基于需求的,即当消费者要求时生产输出线。
在第二组中,PID 保持不变,但生成的行具有不同的 ThreadID。那是因为,生产者和消费者 运行 在不同的线程中。而且生产线的生产不考虑消费者的需求。 Python 中的线程使用原生线程,如 pthread,但由于全局解释器锁,没有两个线程可以同时 运行,这意味着您不会获得真正意义上的并行性。
现在,来到第三组,PID 不同,这意味着消费者 运行 处于从当前进程派生的不同进程中。这实现了真正的并行性,并且可以有效地利用多个 CPU 核心。与多线程一样,无论消费者需求如何,这都会产生生产线。
多线程和多处理使用队列在threads/processes之间进行通信。您可以在创建队列时通过指定项目数来限制生产线的生产。以这种方式,生成行直到队列变满。随着队列中的行被消耗,生产恢复。
现在,最后一组,它使用fork/exec机制来创建一个进程并用指定的可执行文件替换图像。它与第一组相同,但具有不同的 PID 和 ThreadID。这种方式与第三种方式的区别在于进程之间不能使用队列进行通信,而是依赖于管道等IPC机制。此外,producer.py
应该是一个可执行的 python 脚本。在这种情况下,也不管消费者的需求而生产生产线。