歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Python的threading和multiprocessing模塊初探

前言

這兩天為了做一個小項目,研究了一下python的並發編程,所謂並發無非多線程和多進程,最初找到的是threading模塊,因為印象中線程“輕量...”,“切換快...”,“可共享進程資源...”等等,但是沒想到這裡水很深,進而找到了更好的替代品multiprocessing模塊。下面會講一些使用中的經驗。

後面出現的代碼都在Ubuntu10.04 + python2.6.5的環境下測試通過。

一、使用threading模塊創建線程

1、三種線程創建方式

(1)傳入一個函數

這種方式是最基本的,即調用threading中的Thread類的構造函數,然後指定參數target=func,再使用返回的Thread的實例調用start()方法,即開始運行該線程,該線程將執行函數func,當然,如果func需要參數,可以在Thread的構造函數中傳入參數args=(...)。示例代碼如下:

#!/usr/bin/python
#-*-coding:utf-8-*-

import threading
#用於線程執行的函數
def counter(n):
    cnt = 0;
    for i in xrange(n):
        for j in xrange(i):
            cnt += j;
    print cnt;           
   
if __name__ == '__main__':
 #初始化一個線程對象,傳入函數counter,及其參數1000
    th = threading.Thread(target=counter, args=(1000,));
 #啟動線程
    th.start();
 #主線程阻塞等待子線程結束
    th.join();

這個例子關鍵的一句是apply(self.func, self.args); 這裡使用初始化時傳入的函數對象及其參數來進行一次調用。

(3)繼承Thread類

這種方式通過繼承Thread類,並重載其run方法,來實現自定義的線程行為,示例代碼如下:

#!/usr/bin/python
#-*-coding:utf-8-*-

import threading, time, random

def counter():
    cnt = 0;
    for i in xrange(10000):
        for j in xrange(i):
            cnt += j;

class SubThread(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self, name=name);

    def run(self):
        i = 0;
        while i < 4:
            print self.name,'counting...\n';
            counter();
            print self.name,'finish\n';
            i += 1;

if __name__ == '__main__':

    th = SubThread('thread-1');
    th.start();
    th.join();
    print 'all done';

這個例子定義了一個SubThread類,它繼承了Thread類,並重載了run方法,在方法中調用counter4次並打印一些信息,可以看到這種方式比較直觀。在構造函數中要記得先調用父類的構造函數進行初始化。

2、python多線程的限制

python多線程有個討厭的限制,全局解釋器鎖(global interpreter lock),這個鎖的意思是任一時間只能有一個線程使用解釋器,跟單cpu跑多個程序一個意思,大家都是輪著用的,這叫“並發”,不是“並行”。手冊上的解釋是為了保證對象模型的正確性!這個鎖造成的困擾是如果有一個計算密集型的線程占著cpu,其他的線程都得等著....,試想你的多個線程中有這麼一個線程,得多悲劇,多線程生生被搞成串行;當然這個模塊也不是毫無用處,手冊上又說了:當用於IO密集型任務時,IO期間線程會釋放解釋器,這樣別的線程就有機會使用解釋器了!所以是否使用這個模塊需要考慮面對的任務類型。

Copyright © Linux教程網 All Rights Reserved