1、多線程python
一、順序執行單個線程,注意要順序執行的話,須要用join。多線程
1 #coding=utf-8 2 3 from threading import Thread 4 import time 5 6 def my_counter(): 7 i = 0 8 for _ in range(100000000): 9 i = i + 1 10 return True 11 12 def main(): 13 thread_array = {} 14 start_time = time.time() 15 for tid in range(2): 16 t = Thread(target=my_counter) 17 t.start() 18 # join阻塞下個線程,除非當前線程執行完畢 19 t.join() 20 end_time = time.time() 21 print("Total time: {}".format(end_time - start_time)) 22 23 if __name__ == '__main__':
執行結果: 併發
二、同時執行兩個併發線程app
1 #coding=utf-8 2 3 from threading import Thread 4 import time 5 6 def prn_obj(obj): 7 return '\n'.join(['%s:%s' % item for item in obj.__dict__.items()]) 8 9 def my_counter(): 10 i = 0 11 for _ in range(100000000): 12 i = i + 1 13 return True 14 15 def main(): 16 thread_array = {} 17 start_time = time.time() 18 for tid in range(2): 19 t = Thread(target=my_counter) 20 t.start() 21 thread_array[tid] = t 22 for i in range(2): 23 thread_array[i].join() 24 # print("thread type: {}".format(prn_obj(thread_array[i]))) 25 print("thread type: {}".format(thread_array[i].name)) 26 end_time = time.time() 27 print("Total time: {}".format(end_time - start_time)) 28 29 if __name__ == '__main__': 30 main()
下面是用了打印全部屬性的方法,這個方法代碼中註釋了,可重複利用的代碼塊異步
2、多進程async
一、multiprocessing函數
multiprocessing是跨平臺版本的多進程模塊,它提供了一個Process類來表明一個進程對象,下面是示例嗲嗎ui
import os if __name__=='__main__': print 'Process (%s) start...' % os.getpid() pid = os.fork() print pid if pid==0: print 'I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()) else: print 'I (%s) just created a child process (%s).' % (os.getpid(), pid)
這個程序若是用單進程寫則須要執行10秒以上的時間,而用多進程則啓動10個進程並行執行,只須要用1秒多的時間。spa
在python中建議使用多進程而不是多線程,由於在python的多線程中有個全局解釋器鎖,這樣在作併發效率會不是很高。線程
進程和進程直接能夠用不一樣的全局解釋器鎖,能夠提升程序效率。
二、進程間通訊Queue
進程和進程以前是獨立的,若是須要通訊就須要Queue建立的對象來處理
1 from multiprocessing import Process,Queue 2 import time 3 4 def write(q): 5 for i in ['A','B','C','D','E']: 6 print('Put %s to queue' % i) 7 q.put(i) 8 time.sleep(0.5) 9 10 def read(q): 11 while True: 12 v = q.get(True) 13 print('get %s form queue' %v) 14 15 if __name__ == '__main__': 16 q = Queue() 17 pw = Process(target=write,args=(q,)) 18 pr = Process(target=read,args=(q,)) 19 pw.start() 20 pr.start() 21 pr.join() 22 pr.terminate()
三、進程池Pool
1 #coding=utf-8 2 3 from multiprocessing import Pool 4 import time 5 6 def f(x): 7 print x*x 8 time.sleep(2) 9 return x*x 10 11 if __name__ == '__main__': 12 '''定義啓動的進程數量''' 13 pool = Pool(processes=5) 14 res_list = [] 15 16 for i in range(10): 17 ''' 18 以異步並行的方式啓動進程,若是要同步等待的方式, 19 能夠在每次啓動進程以後調用res.get()方法 20 也可使用Pool.appley 21 ''' 22 res = pool.apply_async(f,[i,]) 23 print('--------:',i) 24 res_list.append(res) 25 pool.close() 26 pool.join() 27 for r in res_list: 28 print "result",(r.get(timeout=5))
3、多線程與多進程的對比
在通常狀況下多個進程的內存資源是相互獨立的,而多線程能夠共享同一個進程中的內存資源
1 #coding=utf-8 2 3 from multiprocessing import Process 4 import threading 5 import time 6 lock = threading.Lock() 7 8 def run(info_list,n): 9 lock.acquire() 10 info_list.append(n) 11 lock.release() 12 print('%s' % info_list) 13 14 if __name__ == '__main__': 15 info = [] 16 for i in range(10): 17 # target爲子進程執行的函數,args爲須要給函數傳遞的參數 18 p = Process(target=run,args=[info,i]) 19 p.start() 20 p.join() 21 time.sleep(1)#這裏爲了輸出整齊讓主進程的執行等一會兒進程 22 print('-------------------threading---------------------') 23 for i in xrange(1,10): 24 p = threading.Thread(target=run,args=[info,i]) 25 p.start() 26 p.join()