美文网首页
Python 线程与进程

Python 线程与进程

作者: 曹波波 | 来源:发表于2017-07-18 15:51 被阅读41次

    Python 线程与进程

    Python由于有全锁局的存在(同一时间只能有一个线程执行),并不能利用多核优势。所以,如果程序的多线程进程是CPU密集型的,那多线程并不能带来效率上的提升,相反还可能会因为线程的频繁切换,导致效率下降;如果是IO密集型,多线程进程可以利用IO阻塞等待时的空闲时间执行其他线程,提升效率。

    但我们总会有在程序中实现多并发来提升程序运行效率的情形。在这些情形下,可以适当的利用多进程来实现提升效率。

    另外,python中,为了解决网络请求密集中,延时等待的问题,我们还可是使用协程来提交效率。

    在于IO密集型程序中,多线程应用较多。
    但在网络请求密集中,协程比多线程强上很多。
    在CPU密集中,还是进程应用更多。
    以下是三个例子:

    线程:

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    
    import threading
    import time, datetime
    
    
    # 为线程定义一个函数
    def print_time(thread_name):
        for i in range(3):
            now = datetime.datetime.now()
            print(now, thread_name)
            time.sleep(1)
    
    # 不带线程处理的程序
    for i in range(5):
        threadname = "threadName" + str(i)
        print_time(threadname)
    
    #线程处理
    # for i in range(5):
    #     threadname = "threadName"+str(i)
    #     t = threading.Thread(target=print_time(threadname))
    #     t.start()
    

    运行发现,不带线程处理的程序和线程处理的程序运行顺序是一样的:

    /Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 /Users/caobo/PycharmProjects/ThreadTest/threadTest.py
    
    2017-11-08 11:55:32.889184 threadName0
    2017-11-08 11:55:33.890456 threadName0
    2017-11-08 11:55:34.894145 threadName0
    2017-11-08 11:55:35.899107 threadName1
    2017-11-08 11:55:36.900408 threadName1
    2017-11-08 11:55:37.903821 threadName1
    2017-11-08 11:55:38.907008 threadName2
    2017-11-08 11:55:39.909538 threadName2
    2017-11-08 11:55:40.914680 threadName2
    2017-11-08 11:55:41.918500 threadName3
    2017-11-08 11:55:42.921579 threadName3
    2017-11-08 11:55:43.925748 threadName3
    2017-11-08 11:55:44.928359 threadName4
    2017-11-08 11:55:45.931913 threadName4
    2017-11-08 11:55:46.932414 threadName4
    
    Process finished with exit code 0
    

    每个线程执行完需要3秒,依次执行线程,总耗时15秒。

    进程

    # 进程处理
    if __name__ == "__main__":
        for i in range(5):
            threadName = "threadName" + str(i)
            p = multiprocessing.Process(target=print_time, args=(threadName,))
            p.start()
    

    进程处理运行结果如下:

    /Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 /Users/caobo/PycharmProjects/ThreadTest/threadTest.py
    2017-11-08 11:58:44.045175 threadName0
    2017-11-08 11:58:44.046196 threadName1
    2017-11-08 11:58:44.047036 threadName2
    2017-11-08 11:58:44.048071 threadName3
    2017-11-08 11:58:44.049010 threadName4
    2017-11-08 11:58:45.045841 threadName0
    2017-11-08 11:58:45.046783 threadName1
    2017-11-08 11:58:45.048291 threadName2
    2017-11-08 11:58:45.048476 threadName3
    2017-11-08 11:58:45.050095 threadName4
    2017-11-08 11:58:46.046989 threadName0
    2017-11-08 11:58:46.047063 threadName1
    2017-11-08 11:58:46.048629 threadName2
    2017-11-08 11:58:46.049239 threadName3
    2017-11-08 11:58:46.050937 threadName4
    
    Process finished with exit code 0
    

    每个进程执行完需要3秒,并发执行线程,总耗时3秒。

    进程池

    # 进程池处理
    if __name__ == "__main__":
        pool = multiprocessing.Pool(processes=4)
        for i in range(5):
            threadName = "threadName" + str(i)
            pool.apply_async(print_time, (threadName,))
        pool.close()
        pool.join()
        print("Sub-process(es) done.")
    

    进程池处理结果如下:

    /Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 /Users/caobo/PycharmProjects/ThreadTest/threadTest.py
    2017-11-08 12:01:03.557402 threadName0
    2017-11-08 12:01:03.557552 threadName1
    2017-11-08 12:01:03.557686 threadName2
    2017-11-08 12:01:03.557827 threadName3
    2017-11-08 12:01:04.558322 threadName2
    2017-11-08 12:01:04.558306 threadName0
    2017-11-08 12:01:04.558311 threadName1
    2017-11-08 12:01:04.558322 threadName3
    2017-11-08 12:01:05.558841 threadName1
    2017-11-08 12:01:05.558833 threadName2
    2017-11-08 12:01:05.558841 threadName0
    2017-11-08 12:01:05.558845 threadName3
    2017-11-08 12:01:06.560105 threadName4
    2017-11-08 12:01:07.561340 threadName4
    2017-11-08 12:01:08.561577 threadName4
    Sub-process(es) done.
    
    Process finished with exit code 0
    

    由于设置了进程并发的数量为4,所以,前三秒执行的都是前四个进程的内容(每个进程执行完需要三秒),进程5只能在前四个进程执行完成之后,才开始执行。总耗时6秒。

    修改进程并发数量为5:

    # 进程池处理
    if __name__ == "__main__":
        pool = multiprocessing.Pool(processes=5)
        for i in range(5):
            threadName = "threadName" + str(i)
            pool.apply_async(print_time, (threadName,))
        pool.close()
        pool.join()
        print("Sub-process(es) done.")
    

    运行结果如下:

    /Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 /Users/caobo/PycharmProjects/ThreadTest/threadTest.py
    2017-11-08 12:12:17.210982 threadName0
    2017-11-08 12:12:17.211084 threadName1
    2017-11-08 12:12:17.211188 threadName2
    2017-11-08 12:12:17.211335 threadName3
    2017-11-08 12:12:17.211451 threadName4
    2017-11-08 12:12:18.211480 threadName0
    2017-11-08 12:12:18.211481 threadName2
    2017-11-08 12:12:18.211480 threadName1
    2017-11-08 12:12:18.211785 threadName3
    2017-11-08 12:12:18.211787 threadName4
    2017-11-08 12:12:19.211773 threadName2
    2017-11-08 12:12:19.211784 threadName0
    2017-11-08 12:12:19.212676 threadName1
    2017-11-08 12:12:19.212679 threadName4
    2017-11-08 12:12:19.212679 threadName3
    Sub-process(es) done.
    
    Process finished with exit code 0
    

    修改设置进程并发的数量为5,所以,所有5个进程能够同步执行。每个进程执行完需要三秒,总耗时3秒。

    相关文章

      网友评论

          本文标题:Python 线程与进程

          本文链接:https://www.haomeiwen.com/subject/sreqkxtx.html