[英]How to run multiple functions at the same time?
我试图同时运行 2 个函数。
def func1():
print('Working')
def func2():
print('Working')
func1()
func2()
有谁知道如何做到这一点?
做这个:
from threading import Thread
def func1():
print('Working')
def func2():
print("Working")
if __name__ == '__main__':
Thread(target = func1).start()
Thread(target = func2).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])
与多处理模块或使用多线程相比,使用 Ray 有许多优点。 特别是,相同的代码将在单台机器和机器集群上运行。
有关 Ray 的更多优势,请参阅此相关帖子。
一个选项,看起来像它使在相同的运行两种功能
time ,正在使用threading
模块(此答案中的示例)。
但是,它有一个小的延迟,作为官方 Python 文档
页描述。 一个更好的尝试使用的模块是multiprocessing
。
此外,还有其他 Python 模块可用于异步执行(两段代码同时工作)。 有关它们的一些信息并帮助选择一个,您可以阅读此Stack Overflow 问题。
threading
模块的评论他可能想知道,因为全局解释器锁
即使机器在,它们也不会在完全相同的时间执行
问题有多个 CPU。 wiki.python.org/moin/GlobalInterpreterLock
– Jonas Elfström 2010 年6 月 2 日,11:39
threading
模块不起作用的文档CPython 实现细节:在 CPython 中,由于全局解释器
锁,一次只有一个线程可以执行 Python 代码(即使
某些面向性能的库可能会克服此限制)。如果你想让你的应用更好地利用多核机器的计算资源,建议你使用 multiprocessing 或 concurrent.futures.ProcessPoolExecutor。
然而,线程仍然是一个合适的模型,如果你
想要同时运行多个 I/O 密集型任务。
与多进程不同,线程模块确实同时工作,但时间有点偏离。 下面的代码打印“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
def fun1():
print("Working1")
def fun2():
print("Working2")
t1 = Thread(target=fun1)
t2 = Thread(target=fun2)
t1.start()
t2.start()
我认为您要传达的内容可以通过多处理来实现。 但是,如果您想通过线程进行操作,则可以执行此操作。 这可能有帮助
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()
使用 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()
在 python 中同时运行多个函数的另一种方法是使用我在答案中看不到的asyncio
。
import asyncio
async def func1():
for _ in range(5):
print(func1.__name__)
await asyncio.sleep(0) # switches tasks every iteration.
async def func2():
for _ in range(5):
print(func2.__name__)
await asyncio.sleep(0)
tasks = [func1(), func2()]
await asyncio.gather(*tasks)
出去:
func1
func2
func1
func2
func1
func2
func1
func2
func1
func2
[注意]:
asyncio
语法在 python 3.7 及更高版本上有效下面的代码可以并行运行 2 个函数:
from multiprocessing import Process
def test1():
print("Test1")
def test2():
print("Test2")
if __name__ == "__main__":
process1 = Process(target=test1)
process2 = Process(target=test2)
process1.start()
process2.start()
process1.join()
process2.join()
结果:
Test1
Test2
并且,下面这两组代码可以同时运行两个函数:
from threading import Thread
def test1():
print("Test1")
def test2():
print("Test2")
thread1 = Thread(target=test1)
thread2 = Thread(target=test2)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
from operator import methodcaller
from multiprocessing.pool import ThreadPool
def test1():
print("Test1")
def test2():
print("Test2")
caller = methodcaller("__call__")
ThreadPool().map(caller, [test1, test2])
结果:
Test1
Test2
并且,下面的代码可以同时异步运行 2 个async
函数:
import asyncio
async def test1():
print("Test1")
async def test2():
print("Test2")
async def call_tests():
await asyncio.gather(test1(), test2())
asyncio.run(call_tests())
结果:
Test1
Test2
我可能是错的但是:使用这段代码:
def function_sleep():
time.sleep(5)
start_time = time.time()
p1=Process(target=function_sleep)
p2=Process(target=function_sleep)
p1.start()
p2.start()
end_time = time.time()
我花了一些时间,我希望得到 5/6 秒,而它总是需要传递给 function 睡眠的参数的两倍(在这种情况下为 10 秒)。 怎么了?
对不起伙计们,正如之前评论中提到的,需要调用“join()”。 这非常重要!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.