【Python】多線程編程

一、thread模塊python

二、threading模塊數據結構

三、Queue模塊與多線程互斥多線程

 

簡介:app

        thread和threading模塊容許建立和管理線程,thread模塊提供了基本的線程和鎖的支持,而threading提供了更高級別,功能更強的線程管理功能,Queue模塊dom

容許建立一個能夠用於多個線程之間共享數據的隊列數據結構函數

 

1.thread模塊oop

Thread模塊經常使用函數:ui

image

實例1:spa

# encoding:utf-8
'''
Created on 2014-6-23

@author: Administrator
'''

from time import ctime, sleep
import thread

loops = [4, 2]

def loop(index, nsecs, lock):
    print "start loop,%s at:%s" % (index, ctime())
    sleep(nsecs)
    print "loop %s done at:%s" % (index, ctime())
    lock.release()


def main():
    print "all starting at :%s" % ctime()
    locks = []
    
    nlocks = range(len(loops))
    for i in nlocks:
        lock = thread.allocate_lock()
        lock.acquire()
        locks.append(lock) 
    
    for i in nlocks:
        thread.start_new_thread(loop, (i, loops[i], locks[i]))
        
    for i in nlocks:
        while locks[i].locked():
            pass
        
    print "all done at:%s" % ctime()

if __name__ == "__main__":
    main()

 

2.threading模塊線程

    threading模塊包含對象:

 image

 

  threading模塊Thread類,經常使用函數:

image

 

使用threading.Thread類能夠用多種方法建立線程:

            1、建立一個Thread的實例,參數爲一個函數

            2、建立一個Thread的實例,參數爲一個可調用的類對象

            3、從Thread派生出一個子類,建立一個這個子類的實例

 

方法一:建立一個Thread的實例,參數爲一個函數

# encoding:utf-8
'''
Created on 2014-6-23

@author: Administrator
'''

import threading
from time import ctime, sleep

loops = [4, 2]

def loop(nloop, nsec):
    print "strating loop %s at:%s" % (nloop, ctime())
    sleep(nsec)
    print "end loop %s at:%s" % (nloop, ctime())
    
def main():
    print threading.__file__
    print "all start at:%s" % ctime()
    threads = []
    nloops = range(len(loops))
    
    for i in nloops:
        t = threading.Thread(target=loop, args=(i, loops[i]))#建立一個Thread實例,傳遞一個函數
        threads.append(t)
        
    for i in nloops:
        threads[i].start()
        
    for i in nloops:
        threads[i].join()
        
    print "all end at:%s" % ctime()


if __name__ == "__main__":
    main()

 

方法二:建立一個Thread的實例,參數爲一個可調用的類對象

# encoding:utf-8
'''
Created on 2014-6-24

@author: Administrator
'''

import threading
from time import sleep, ctime

loops = [4, 2]

class ThreadingCls(object):
    def __init__(self, func, args, name=''):
        self.name = name
        self.func = func
        self.args = args
        
    #python 可調用對象,重寫__call__方法,經過ThreadingCls(...)調用
    def __call__(self):
        self.func(*self.args)   #函數調用,參數爲元組*(...)
        
def loop(nloop, nsec):
    print "staring loop %s at:%s" % (nloop, ctime())
    sleep(nsec)
    print "end loop %s at:%s" % (nloop, ctime())

def main():
    print "all start at:%s" % ctime()
    threads = []
    nloops = range(len(loops))
    
    for i in nloops:
        t = threading.Thread(target=ThreadingCls(loop, (i, loops[i]), loop.__name__))
        threads.append(t)
    
    for i in nloops:
        threads[i].start()
        
    for i in nloops:
        threads[i].join()

    print "all end at:%s" % ctime()
    
    
if __name__ == "__main__":
    main()

 

方法三:從Thread派生出一個子類,建立一個這個子類的實例

# encoding:utf-8
'''
Created on 2014-6-24

@author: Administrator
'''

import threading
from time import sleep, ctime

loops = [4, 2]

"""
    子類化Thread建立多線程:
    (1)構造函數__init__須要調用基類的構造函數
    (2)須要重寫run方法
"""
class ThreadingDerived(threading.Thread):
    
    def __init__(self, func, args, name=''):
        super(ThreadingDerived, self).__init__()
        self.name = name
        self.func = func
        self.args = args

    def run(self):
        print "%s running at:%s" % (self.name, ctime())
        self.func(*self.args)


def loop(nloop, nsec):
    print "staring loop %s at:%s" % (nloop, ctime())
    sleep(nsec)
    print "end loop %s at:%s" % (nloop, nsec) 
    
def main():
    print "all start at:%s" % ctime()
    threads = []
    nloops = range(len(loops))
    
    for i in nloops:
        t = ThreadingDerived(loop, (i, loops[i]), loop.__name__)
        threads.append(t)
    
    for i in nloops:
        threads[i].start()
        
    for i in nloops:
        threads[i].join()

    print "all end at:%s" % ctime()


if __name__ == "__main__":
    main()

 

三、Queue模塊與多線程互斥

Queue模塊經常使用函數:

image

 

實例3. 生產者消費者

 

# encoding:utf-8
'''
Created on 2014-6-24

@author: Administrator
'''

from threading_subcls import ThreadingDerived
from Queue import Queue
from time import ctime, sleep
from random import randint

gl_queue = Queue(3)

def consumer():
    while True:
        if gl_queue.empty():
            sleep(2)
        else:
            print "consum %s at:%s" % (gl_queue.get(1), ctime())    #get函數,從隊列中取一個對象,block=1,函數會一直阻塞直到隊列有空間爲止

def producer():
    while True:
        if gl_queue.full():
            sleep(2)
        else:
            pdata = randint(0, 3)
            gl_queue.put(pdata, 1)  #把pdata放入隊列,block=1,函數會一直阻塞到隊列有空間爲止
            print "produce %s at:%s" % (pdata, ctime())

def main():
    funcs = [consumer, producer]
    ncount = range(len(funcs))
    threads = []
    
    for i in ncount:
        t = ThreadingDerived(funcs[i], (), funcs[i].__name__)
        threads.append(t)
    
    for i in ncount:
        threads[i].start()
        
    for i in ncount:
        threads[i].join()


if __name__ == "__main__":
    main()

 

線程互斥:Python主要有四種數據同步機制:互斥鎖(Lock),條件變量(Condition), 信號量(Semaphore)和同步隊列,在threading模塊中鎖對象用threading.Lock()建立

實例4.

# encoding:utf-8
'''
Created on 2014-6-24

@author: Administrator
'''

import threading
from threading_subcls import ThreadingDerived
from time import sleep 

gl_lock = threading.Lock()  #互斥鎖
gl_count = 0
gl_max = 3

def consumer():
    global gl_count, gl_lock
    while True:
        gl_lock.acquire()
        if gl_count > 0:
            gl_count -= 1
            print "consume %s-->%s" % (gl_count + 1, gl_count)
            gl_lock.release()
        else:
            gl_lock.release()
            print "%s wait producer..." % threading.current_thread().getName()
            sleep(3)
        
def producer():
    global gl_count, gl_lock, gl_max
    while True:
        if gl_count >= gl_max:
            sleep(1)
            continue
        gl_lock.acquire()
        gl_count += 1
        print "produce %s-->%s" % (gl_count - 1, gl_count)
        gl_lock.release()
        

def main():
    funcs = [consumer, consumer, producer]
    ncount = range(len(funcs))
    threads = []
    
    for i in ncount:
        t = ThreadingDerived(funcs[i], (), "%s#%s" % (funcs[i].__name__, i))
        threads.append(t)
    
    for i in ncount:
        threads[i].start()
        
    for i in ncount:
        threads[i].join()
         
if __name__ == "__main__":
    main()
相關文章
相關標籤/搜索