Python宝典第23章:多线程编程

来源:互联网 发布:php网站访问量统计代码 编辑:程序博客网 时间:2024/05/21 17:22

Python3中,通过threading模块提供了对多线程编程的支持。

通过继承threading模块中的Thread类创建新类,在新类中重载run方法。然后通过start方法创建线程。

<span style="font-size:14px;">>>> import threading>>> class mythread(threading.Thread):def __init__(self, num):threading.Thread.__init__(self)self.num=numdef run(self): #重载run方法print('I am ', self.num)>>> t1=mythread(1)>>> t2=mythread(2)>>> t3=mythread(3)>>> t1.start()>>> I am  1t2.start() #启动线程实际上是调用run方法I am >>>  2t3.start()I am >>>  3</span>

<span style="font-size:14px;">>>> import threading>>> def run(x,y):for i in range(x,y):print(i)>>> t1=threading.Thread(target=run, args=(15,20))>>> t1.start()>>> 1516171819t2=threading.Thread(target=run, args=(7,11))>>> t2.start()7>>> 8910</span>

Thread对象还有以下方法:

join:如果一个线程或者函数在执行过程中调用另一线程,并且必须等待后一线程完成操作后才能继续当前线程的执行。可以调用join方法。

<span style="font-size:14px;">>>> import threading>>> import time>>> class Mythread(threading.Thread):def __init__(self, id):threading.Thread.__init__(self)self.id=iddef run(self):x=0time.sleep(60)print(self.id)>>> def func():t.start()for i in range(5):print(i)>>> t=Mythread(2)>>> func()01234>>> 2def func():t.start()t.join()for i in range(5):print(i)>>> t=Mythread(3)>>> func()301234</span>

isAlive方法查看线程是否运行。

线程名可以区分不同线程,以便控制。可以在类的初始化函数中定义,也可以使用setName方法设置。getName方法可以获得线程名。

<span style="font-size:14px;">>>> import threading>>> class mythread(threading.Thread):def __init__(self, threadname):threading.Thread.__init__(self, name=threadname)def run(self):print(self.getName())>>> t1=mythread('t1')>>> t1.getName()'t1'>>> t1.setName('T')>>> t1.getName()'T'>>> t2=mythread('t2')>>> t2.start()t2>>> t2.getName()'t2'>>> t2.setName('TT')>>> t2.getName()'TT'</span>

daemon属性:子线程随主线程一起结束


线程同步:

简单的同步使用Lock和Rlock

# -*- coding:utf-8 -*-# file: syn.py#import threadingimport timeclass mythread(threading.Thread):    def __init__(self, threadname):        threading.Thread.__init__(self, name=threadname)    def run(self):            global x            lock.acquire()            for i in range(3):                x=x+1            time.sleep(2)            print(x)            lock.release()lock=threading.RLock()t1=[]for i in range(10):    t=mythread(str(i))    t1.append(t)x=0for i in t1:    i.start()

条件变量保持线程同步:

Condition对象提供了对复杂线程同步的支持。该对象可以在某些事件触发后才处理数据,除了acquire和lock方法,还有wait,notify,notifyAll方法。

# -*- coding:utf-8 -*-# file: pc.py#import threadingclass producer(threading.Thread):    def __init__(self, threadname):        threading.Thread.__init__(self, name=threadname)    def run(self):            global x            con.acquire()            if x==1000000:                con.wait()                pass            else:                for i in range(1000000):                    x=x+1                con.notify()            print(x)            con.release()class consumer(threading.Thread):    def __init__(self, threadname):        threading.Thread.__init__(self, name=threadname)    def run(self):            global x            con.acquire()            if x==0:                con.wait()                pass            else:                for i in range(1000000):                    x=x-1                con.notify()            print(x)            con.release()con=threading.Condition()x=0p=producer('Porducer')c=consumer('Consumer')p.start()c.start()p.join()c.join()print(x)

使用队列让线程同步:

Queue对象。

# -*- coding:utf-8 -*-# file: queue.py#import threadingimport timeimport queueclass producer(threading.Thread):    def __init__(self, threadname):        threading.Thread.__init__(self, name=threadname)    def run(self):            global queue            queue.put(self.getName())            print(self.getName(), 'put ', self.getName(), ' to queue')class consumer(threading.Thread):    def __init__(self, threadname):        threading.Thread.__init__(self, name=threadname)    def run(self):            global queue            queue.put(self.getName())            print(self.getName(), 'get ', self.getName(), ' from queue')queue=queue.Queue()plist=[]clist=[]for i in range(10):    p=producer('Producer' + str(i))    plist.append(p)for i in range(10):    c=consumer('Consumer' + str(i))    clist.append(c)for i in plist:    i.start()    i.join()for i in clist:    i.start()    i.join()

线程间通信:

Event对象,由线程设置型号标志,如果信号标志为真则其他线程等待,知道信号解除。

set(), isSet(), clear(), wait()

# -*- coding:utf-8 -*-# file: event.py#import threadingclass mythread(threading.Thread):    def __init__(self, threadname):        threading.Thread.__init__(self, name=threadname)    def run(self):        global event        if event.isSet():            event.clear()            event.wait()            print(self.getName())        else:            print(self.getName())            event.set()event=threading.Event()event.set()t1=[]for i in range(10):    t=mythread(str(i))    t1.append(t)for i in t1:    i.start()


微线程:Stackless Python ->Python的修改版

stackless模块,tasklet对象,schedule对象控制顺序

0 0
原创粉丝点击