【发布时间】:2011-02-26 18:41:39
【问题描述】:
我正在尝试让 2 个函数同时运行。
def func1():
print 'Working'
def func2():
print 'Working'
func1()
func2()
有人知道怎么做吗?
【问题讨论】:
标签: python multithreading parallel-processing
我正在尝试让 2 个函数同时运行。
def func1():
print 'Working'
def func2():
print 'Working'
func1()
func2()
有人知道怎么做吗?
【问题讨论】:
标签: python multithreading parallel-processing
这样做:
from threading import Thread
def func1():
print('Working')
def func2():
print("Working")
if __name__ == '__main__':
Thread(target = func1).start()
Thread(target = func2).start()
【讨论】:
The answer about threading 很好,但你需要更具体地说明你想做什么。
如果您有两个都使用大量 CPU 的函数,那么线程(在 CPython 中)可能会让您一事无成。然后你可能想看看multiprocessing module 或者你可能想使用jython/IronPython。
如果 CPU 受限的性能是原因,您甚至可以在(非线程)C 中实现,并获得比在 python 中执行两个并行操作更大的加速。
没有更多的信息,很难想出一个好的答案。
【讨论】:
一个选项,看起来它可以让两个函数同时运行
时间,正在使用threading 模块(this 答案中的示例)。
但是,正如官方 Python 文档
page 所述,它有一点延迟。可以尝试使用的更好的模块是 multiprocessing。
此外,还有其他 Python 模块可用于异步执行(两段代码同时工作)。有关它们的一些信息和帮助选择一个,您可以阅读this Stack Overflow 问题。
threading 模块的评论由于全局解释器锁定,他可能想知道这一点
即使机器在
中,它们也不会同时执行 问题有多个 CPU。 wiki.python.org/moin/GlobalInterpreterLock
– 乔纳斯·埃尔夫斯特罗姆 Jun 2 '10 at 11:39
threading 模块不工作的内容CPython 实现细节:在 CPython 中,由于 Global Interpreter
锁,一次只能有一个线程执行 Python 代码(尽管
某些面向性能的库可能会克服这个限制)。如果您希望您的应用程序更好地利用多核机器的计算资源,建议您使用 multiprocessing 或 concurrent.futures.ProcessPoolExecutor。
但是,如果您
,线程仍然是一个合适的模型 想要同时运行多个 I/O 密集型任务。
【讨论】:
thr1 = Process(target=run_foo(), args=()) 行不应该创建线程(因为我没有运行thr1.start()) 实际上创建了它,因此应该由@987654334 启动的进程@窃取执行,所以没有多线程。
试试这个
from threading import Thread
def fun1():
print("Working1")
def fun2():
print("Working2")
t1 = Thread(target=fun1)
t2 = Thread(target=fun2)
t1.start()
t2.start()
【讨论】:
与多进程不同,线程模块确实同时工作,但时间有点不对。下面的代码打印一个“1”和一个“2”。它们分别由不同的函数调用。我确实注意到,当打印到控制台时,它们的时间会略有不同。
from threading import Thread
def one():
while(1 == num):
print("1")
time.sleep(2)
def two():
while(1 == num):
print("2")
time.sleep(2)
p1 = Thread(target = one)
p2 = Thread(target = two)
p1.start()
p2.start()
输出:(注意空格是打印之间的等待)
1
2
2
1
12
21
12
1
2
不确定是否有办法纠正这个问题,或者它是否重要。只是我注意到了。
【讨论】:
我认为您试图传达的内容可以通过多处理来实现。但是,如果您想通过线程执行此操作,则可以执行此操作。 这可能会有所帮助
from threading import Thread
import time
def func1():
print 'Working'
time.sleep(2)
def func2():
print 'Working'
time.sleep(2)
th = Thread(target=func1)
th.start()
th1=Thread(target=func2)
th1.start()
【讨论】:
这可以通过Ray 优雅地完成,该系统可让您轻松并行化和分发 Python 代码。
要并行化您的示例,您需要使用@ray.remote decorator 定义您的函数,然后使用.remote 调用它们。
import ray
ray.init()
# Define functions you want to execute in parallel using
# the ray.remote decorator.
@ray.remote
def func1():
print("Working")
@ray.remote
def func2():
print("Working")
# Execute func1 and func2 in parallel.
ray.get([func1.remote(), func2.remote()])
如果func1() 和func2() 返回结果,则需要稍微重写上面的代码,将ray.get([func1.remote(), func2.remote()]) 替换为:
ret_id1 = func1.remote()
ret_id2 = func1.remote()
ret1, ret2 = ray.get([ret_id1, ret_id2])
与multiprocessing 模块相比,使用Ray 或使用多线程有许多优点。特别是,相同的代码可以在单台机器上运行,也可以在一组机器上运行。
有关 Ray 的更多优势,请参阅this related post。
【讨论】:
使用 APscheduler 进行测试:
from apscheduler.schedulers.background import BackgroundScheduler
import datetime
dt = datetime.datetime
Future = dt.now() + datetime.timedelta(milliseconds=2550) # 2.55 seconds from now testing start accuracy
def myjob1():
print('started job 1: ' + str(dt.now())[:-3]) # timed to millisecond because thats where it varies
time.sleep(5)
print('job 1 half at: ' + str(dt.now())[:-3])
time.sleep(5)
print('job 1 done at: ' + str(dt.now())[:-3])
def myjob2():
print('started job 2: ' + str(dt.now())[:-3])
time.sleep(5)
print('job 2 half at: ' + str(dt.now())[:-3])
time.sleep(5)
print('job 2 done at: ' + str(dt.now())[:-3])
print(' current time: ' + str(dt.now())[:-3])
print(' do job 1 at: ' + str(Future)[:-3] + '''
do job 2 at: ''' + str(Future)[:-3])
sched.add_job(myjob1, 'date', run_date=Future)
sched.add_job(myjob2, 'date', run_date=Future)
我得到了这些结果。这证明它们是同时运行的。
current time: 2020-12-15 01:54:26.526
do job 1 at: 2020-12-15 01:54:29.072 # i figure these both say .072 because its 1 line of print code
do job 2 at: 2020-12-15 01:54:29.072
started job 2: 2020-12-15 01:54:29.075 # notice job 2 started before job 1, but code calls job 1 first.
started job 1: 2020-12-15 01:54:29.076
job 2 half at: 2020-12-15 01:54:34.077 # halfway point on each job completed same time accurate to the millisecond
job 1 half at: 2020-12-15 01:54:34.077
job 1 done at: 2020-12-15 01:54:39.078 # job 1 finished first. making it .004 seconds faster.
job 2 done at: 2020-12-15 01:54:39.091 # job 2 was .002 seconds faster the second test
【讨论】:
如果您还想等待直到两个功能都完成:
from threading import Thread
def func1():
print 'Working'
def func2():
print 'Working'
# Define the threads and put them in an array
threads = [
Thread(target = self.func1),
Thread(target = self.func2)
]
# Func1 and Func2 run in separate threads
for thread in threads:
thread.start()
# Wait until both Func1 and Func2 have finished
for thread in threads:
thread.join()
【讨论】: