python 3.x 多线程与多进程对比

多线程与多进程对比

  • 由于在python中有一把GIL锁,所以说对于某一些任务来说,这里主要指的是耗cpu的操作,因为有一把GIL锁的存在,所以说我们python中的多线程实际上是无法充分的利用多核的优势,
    所以说对于某些耗cpu的操作来说,我们用多线程编程就无法达到一个并行的操作,所以python中也提供了多进程编程,多进程编程就可以充分的利用多个cpu并发的这么一个特性,去提高我们的运行效率,所以说多cpu的操作,用多进程编程.
  • 对于IO操作来说,我们往往的瓶颈不在于cpu,所以使用多线程编程.IO操作也可使用多进程编程,但是对于操作系统来说进程间的切换代价要高于线程的切换.当我们同时运行几十个线程,对于操作系统来说,线程的切换性能是要比进程间切换性能要高的,
    所以说在特定的情况下,能够使用多线程的情况下尽量使用多线程
  • 举例说明:
    • 对于耗费cpu的操作,主要指的是计算,计算类型的操作都是耗cpu的(比如数学运算,图形处理.).
      显卡里的GPU的运算速度是高于CPU的(对于图形计算来说,多进程是比多线程高的),所以说对于耗费cpu的操作,多进程优于多线程  
  • 多线程的稳定性高于多进程
  • 注意:
    • 在windows系统下使用多进程编程的时候,不管使用ProcessPoolExecutor还是使用MultiProcessPoolExecutor来进行多进程编程,多进程的执行代码没有放在if __name__ == '__main__':语句下,  
    • 会抛异常.  
      • A process in the process pool was terminated abruptly while the future was running or pending.(在将来运行或挂起时,进程池中的进程突然终止)。    
    • 在Linux下是没有这个问题的,只有在windows下才需要将多进程编程的代码写在if __name__ == '__main__':语句下.  
 1 """
 2 斐波拉契计算是耗cpu的.来看看斐波拉契计算在多线程和多进程的一个表现.
 3 
 4 多线程下的斐波拉契的表现
 5 """
 6 
 7 import time
 8 from concurrent.futures import ThreadPoolExecutor, as_completed
 9 
10 
11 def fib(n):
12     """斐波拉契"""
13     if n <= 2:
14         return 1
15 
16     return fib(n - 1) + fib(n - 2)
17 
18 
19 if __name__ == '__main__':
20 
21     # 多线程编程,ThreadPoolExecutor继承Executor,而Executor类中实现魔法函数__enter__()和__exit__()
22     #     def __exit__(self, exc_type, exc_val, exc_tb):
23     #         self.shutdown(wait=True) --> 关闭线程池
24     #         return False
25     # --------------------------------------------------------------------------------------
26     # 1.创建线程池执行者
27     with ThreadPoolExecutor(3) as executor:
28         # 2.提交所有任务(需要执行的函数fib以及函数所需要的参数num),返回所有任务的列表.
29         all_task = [executor.submit(fib, num) for num in range(25, 35)]
30 
31         start_time = time.time()
32 
33         # 3.判断任务是否执行完成,获取执行完成的任务的结果.
34         for future in as_completed(all_task):
35             data = future.result()
36             print("exe result: {}".format(data))
37 
38         # 运行时间13.77秒
39         print("run time: {}".format(time.time() - start_time))
40 
41 """
42 输出结果:
43     exe result: 75025
44     exe result: 121393
45     exe result: 196418
46     exe result: 317811
47     exe result: 514229
48     exe result: 832040
49     exe result: 1346269
50     exe result: 2178309
51     exe result: 3524578
52     exe result: 5702887
53     run time: 13.77378797531128
54 """

 

 

 1 """
 2 斐波拉契计算是耗cpu的.来看看斐波拉契计算在多线程和多进程的一个表现.
 3 多进程下的斐波拉契的表现
 4 """
 5 
 6 
 7 import time
 8 from concurrent.futures import ProcessPoolExecutor, as_completed
 9 
10 
11 def fib(n):
12     """斐波拉契"""
13     if n <= 2:
14         return 1
15 
16     return fib(n - 1) + fib(n - 2)
17 
18 
19 if __name__ == '__main__':
20     # 1.创建进程池执行者
21     with ProcessPoolExecutor(3) as executor:
22         # 2.提交所有任务(需要执行的函数fib以及函数所需要的参数num),返回所有任务的列表.
23         all_task = [executor.submit(fib, num) for num in range(25, 35)]
24 
25         start_time = time.time()
26 
27         # 3.判断任务是否执行完成,获取执行完成的任务的结果.
28         for future in as_completed(all_task):
29             data = future.result()
30             print("exe result: {}".format(data))
31 
32         # 运行时间3.15秒
33         print("run time: {}".format(time.time() - start_time))
34 
35 """
36 输出结果:
37     exe result: 75025
38     exe result: 121393
39     exe result: 196418
40     exe result: 317811
41     exe result: 514229
42     exe result: 832040
43     exe result: 1346269
44     exe result: 2178309
45     exe result: 3524578
46     exe result: 5702887
47     run time: 3.1521804332733154
48 
49 通过多线程与多进程执行同样的任务,执行的时间相差很的大
50 得出结论:
51     对于耗费cpu的操作,多进程优于多线程
52 """

 

 

 1 """
 2 对于IO操作来说,多线程优于多进程
 3 
 4 多线程对IO操作
 5 """
 6 
 7 import time
 8 from concurrent.futures import ThreadPoolExecutor, as_completed
 9 
10 
11 # 用sleep来模拟IO操作
12 def random_sleep(n):
13     time.sleep(n)
14     return n
15 
16 
17 if __name__ == '__main__':
18     with ThreadPoolExecutor(3) as executor:
19         # 每次sleep 2秒,执行30次.
20         all_task = [executor.submit(random_sleep, num) for num in [2] * 30]
21 
22         start_time = time.time()
23 
24         for future in as_completed(all_task):
25             data = future.result()
26             print("exe result: {}".format(data))
27 
28     print("run time: {}".format(time.time() - start_time))
29 
30 """
31 输出结果:
32     输出30个 : exe result: 2
33     
34     run time: 20.00214409828186秒
35 """

 

 

 1 """
 2 对于IO操作来说,多线程优于多进程
 3 
 4 多进程对IO操作
 5 """
 6 import time
 7 from concurrent.futures import ProcessPoolExecutor, as_completed
 8 
 9 
10 def random_sleep(n):
11     time.sleep(n)
12     return n
13 
14 
15 if __name__ == '__main__':
16     with ProcessPoolExecutor(3) as executor:
17         all_task = [executor.submit(random_sleep, num) for num in [2] * 30]
18 
19         start_time = time.time()
20 
21         for future in as_completed(all_task):
22             data = future.result()
23             print("exe result: {}".format(data))
24 
25         print("run time: {}".format(time.time() - start_time))
26 
27 """
28 输出结果:
29     输出30个 : exe result: 2
30     
31     run time: 20.598177909851074秒
32 """

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

********

posted on 2019-05-02 08:44  jaydenjune  阅读(66)  评论(0)    收藏  举报

导航