【Python】多线程编程

1、thread模块

2、threading模块

3、Queue模块与多线程互斥

 

简介:

        thread和threading模块允许创建和管理线程,thread模块提供了基本的线程和锁的支持,而threading提供了更高级别,功能更强的线程管理功能,Queue模块

允许创建一个可以用于多个线程之间共享数据的队列数据结构

 

1.thread模块

Thread模块常用函数:

image

实例1:

# 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类可以用多种方法创建线程:

            一、创建一个Thread的实例,参数为一个函数

            二、创建一个Thread的实例,参数为一个可调用的类对象

            三、从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()

 

3、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()
posted @ 2014-06-24 18:59  罗松超  阅读(451)  评论(0编辑  收藏  举报