python多線程、多進程、協程的使用

本文主要介紹多線程、多進程、協程的最多見使用,每一個的詳細說明與介紹有時間會在之後的隨筆中體現。python

1、多線程多線程

1.python經過兩個標準庫thread和threading提供對線程的支持。thread提供了低級別的、原始的線程以及一個簡單的鎖。threading經過對thread模塊進行二次封裝,提供了更方便的API來操做線程。接下來只介紹threading的常見用法。app

2.使用函數

import threading
import time 


def Traversal_5(interval):
    for i in xrange(5):
        print 'Traversal_5:',i
        time.sleep(interval)

def Traversal_10(interval):
    for i in xrange(10):
        print 'Traversal_10:',i
        time.sleep(interval)

if __name__ == '__main__':
    print 'start time:'
    t1 = int(time.time()) 
    tasks=[Traversal_5,Traversal_10] 
    threads = []
    for task in tasks:
        t = threading.Thread(target=task,args=(1,))
        threads.append(t)
    for t in threads:
        t.setDaemon(True)
        t.start()
    for t in threads:
        t.join()
    print 'end main total time:',int(time.time())-t1

3.結果性能

4.結果分析spa

單線程運行這完兩個函數至少應該須要15秒,多線程狀況下,兩個函數同時運行,總共用時是取最長的Traversal_10這個函數的時間線程

2、多進程code

1.因爲GIL的存在,python中的多線程其實並非真正的多線程,若是想要充分地使用多核CPU的資源,在python中大部分狀況須要使用多進程。Python提供了很是好用的多進程包multiprocessing,與threading.Thread相似,它能夠利用multiprocessing.Process對象來建立一個進程。接下來只介紹multiprocessing的常見用法。協程

2.使用對象

import multiprocessing 
import time 

class Traversal(object):
    def __init__(self,interval, name):
        self.interval = interval 
        self.name = name
        self._rungevent(self.interval, self.name)

    def _rungevent(self, interval, name):
        for i in xrange(5):
            print 'process name:',name,'\tindex:',i
            time.sleep(interval)

if __name__ == '__main__':
    print 'start time:'
    t1 = int(time.time()) 
    jobs = []
    for x in xrange(2):
        p = multiprocessing.Process(target = Traversal, args=(1,'Traversal_'+str(x)))
        p.start()
        jobs.append(p)
    for job in jobs:
        job.join() 
    print 'end main total time:',int(time.time())-t1

3.結果

4.結果分析

此程序至關於遍歷兩次0-5的函數,按理說,時間應該是10秒,由於開了2個進程,因此總花時和一次遍歷時間相等

3、協程

1.協程,又稱微線程,纖程。協程的特色在因而一個線程執行,那和多線程比,協程有何優點?最大的優點就是協程極高的執行效率。由於子程序切換不是線程切換,而是由程序自身控制,所以,沒有線程切換的開銷,和多線程比,線程數量越多,協程的性能優點就越明顯。第三方的gevent爲Python提供了比較完善的協程支持。接下來只介紹gevent用法

2.使用

from gevent import monkey; monkey.patch_all(); 
from gevent.pool import Pool 
import time 

def Traversal(job):
    print 'job:',job
    time.sleep(1)


if __name__ == '__main__':
    print 'start time:'
    t1 = int(time.time())
    jobs = [i for i in xrange(10)] 
    pool = Pool(5)
    pool.map(Traversal, jobs)
    print 'end main total time:',int(time.time())-t1

3.結果

3.結果分析

此程序本質是遍歷0-10之間的數,應該用時10秒,因爲使用了協程,開啓了5個池,因此時間減小到2秒,大大減小運行時間。

4、多進程+協程

1.由於協程是一個線程執行,那怎麼利用多核CPU呢?最簡單的方法是多進程+協程,既充分利用多核,又充分發揮協程的高效率,可得到極高的性能。

2.使用

import multiprocessing 
from gevent import monkey; monkey.patch_all(); 
from gevent.pool import Pool
import time 

def Traver(job):
    print 'job:',job
    time.sleep(1)

class Traversal(object):
    def __init__(self,interval, name):
        self.interval = interval 
        self.name = name
        self._rungevent(self.interval, self.name)

    def _rungevent(self, interval, name):
        jobs = [i for i in xrange(5)] 
        pool = Pool(5)
        pool.map(Traver, jobs) 

if __name__ == '__main__':
    print 'start time:'
    t1 = int(time.time()) 
    jobs = []
    for x in xrange(2):
        p = multiprocessing.Process(target = Traversal, args=(1,'Traversal_'+str(x)))
        p.start()
        jobs.append(p)
    for job in jobs:
        job.join() 
    print 'end main total time:',int(time.time())-t1

3.結果

4.結果分析

此程序本質上是遍歷2次0-5之間數據,應該使用10秒才能運行完,因爲開啓了兩個線程和5個池的協程,結果1秒就運行完了。

5、總結

從以上小例子看,多進程、多線程和協程沒有啥差異,本文也只是主要介紹其用法。可是,要是在IO密集和CPU密集的任務下,各個之間的區別就會顯現,這裏就不作介紹。

相關文章
相關標籤/搜索