Python多线程学习,python多线程

Python八线程学习,python四十多线程

后生可畏、Python中的线程使用:

    Python中使用线程有三种方法:函数恐怕用类来包装线程对象。

1、  函数式:调用thread模块中的start_new_thread(卡塔尔(قطر‎函数来爆发新线程。如下例:

import time  
import thread  
def timer(no, interval):  
    cnt = 0  
    while cnt<10:  
        print 'Thread:(%d) Time:%sn'%(no, time.ctime())  
        time.sleep(interval)  
        cnt+=1  
    thread.exit_thread()  


def test(): #Use thread.start_new_thread() to create 2 new threads  
    thread.start_new_thread(timer, (1,1))  
    thread.start_new_thread(timer, (2,2))  

if __name__=='__main__':  
    test()  

 
 上面包车型地铁事例定义了多少个线程函数timer,它打字与印刷出10条时间记下后脱离,每便打字与印刷的距离由interval参数决定。thread.start_new_thread(function,
args[,
kwargs]卡塔尔国的首先个参数是线程函数(本例中的timer方法),第二个参数是传递给线程函数的参数,它必需是tuple类型,kwargs是可选参数。

    线程的收尾能够等待线程自然终止,也得以在线程函数中调用thread.exit(State of Qatar或thread.exit_thread()方法。

2、  创立threading.Thread的子类来包装三个线程对象,如下例:

import threading  
import time  
class timer(threading.Thread): #The timer class is derived from the class threading.Thread  
    def __init__(self, num, interval):  
        threading.Thread.__init__(self)  
        self.thread_num = num  
        self.interval = interval  
        self.thread_stop = False  

    def run(self): #Overwrite run() method, put what you want the thread do here  
        while not self.thread_stop:  
            print 'Thread Object(%d), Time:%sn' %(self.thread_num, time.ctime())  
            time.sleep(self.interval)  
    def stop(self):  
        self.thread_stop = True  


def test():  
    thread1 = timer(1, 1)  
    thread2 = timer(2, 2)  
    thread1.start()  
    thread2.start()  
    time.sleep(10)  
    thread1.stop()  
    thread2.stop()  
    return  

if __name__ == '__main__':  
    test()  

 
 就作者个人来说,相比心仪第两种方法,即开立本人的线程类,需要时重写threading.Thread类的主意,线程的决定能够由友好定制。

threading.Thread类的运用:

1,在和谐的线程类的__init__里调用threading.Thread.__init__(self,
name = threadname)

Threadname为线程的名字

2, run(卡塔尔(قطر‎,平常须求重写,编写代码实现做必要的意义。

3,getName(卡塔尔(قطر‎,拿到线程对象名称

4,setName(卡塔尔(قطر‎,设置线程对象名称

5,start(卡塔尔(قطر‎,运维线程

6,jion([timeout]卡塔尔国,等待另一线程停止后再运维。

7,setDaemon(bool卡塔尔,设置子线程是不是随主线程一齐甘休,必须在start(State of Qatar从前调用。默感到False。

8,isDaemon(State of Qatar,判别线程是不是随主线程一同停止。

9,isAlive(State of Qatar,检查线程是或不是在运维中。

    其余threading模块本人也提供了成千上万主意和任何的类,能够扶助大家越来越好的应用和拘系线程。能够参照

 

 

万少年老成多少个线程对象t1和t2都要对num=0举办增1运算,t1和t2都各对num修正10遍,num的最后的结果应当为20。不过由于是多线程访谈,有超大希望现身上面情形:在num=0时,t1拿到num=0。系统那时候把t1调节为”sleeping”状态,把t2调换为”running”状态,t2页得到num=0。然后t2对得到的值进行加1并赋给num,使得num=1。然后系统又把t2调节为”sleeping”,把t1转为”running”。线程t1又把它前面获得的0加1后赋值给num。这样,明明t1和t2都形成了1次加1工作,但结果一近年来后是num=1。

    上面包车型地铁case描述了七十多线程意况下最广泛的难题之后生可畏:数据分享。当七个线程都要去修正某叁个分享数据的时候,大家需求对数据访谈进行同盟。

1、  简单的一路

最简便的同盟机制正是“锁”。锁对象由threading.途乐Lock类创造。线程可以接受锁的acquire(卡塔尔国方法赢得锁,那样锁就进去“locked”状态。每一趟唯有一个线程能够获得锁。假诺当另贰个线程试图拿走那一个锁的时候,就能够被系统成为“blocked”状态,直到那么些全数锁的线程调用锁的release(State of Qatar方法来释放锁,这样锁就能够进来“unlocked”状态。“blocked”状态的线程就能够收下二个通报,并有权利获取锁。假诺多少个线程处于“blocked”状态,全部线程都会先消释“blocked”状态,然后系统筛选几个线程来获得锁,其余的线程继续沉默(“blocked”)。

Python中的thread模块和Lock对象是Python提供的低端线程序调控制工具,使用起来特别轻松。如下例所示:

import thread  
import time  
mylock = thread.allocate_lock()  #Allocate a lock  
num=0  #Shared resource  

def add_num(name):  
    global num  
    while True:  
        mylock.acquire() #Get the lock   
        # Do something to the shared resource  
        print 'Thread %s locked! num=%s'%(name,str(num))  
        if num >= 5:  
            print 'Thread %s released! num=%s'%(name,str(num))  
            mylock.release()  
            thread.exit_thread()  
        num+=1  
        print 'Thread %s released! num=%s'%(name,str(num))  
        mylock.release()  #Release the lock.  

def test():  
    thread.start_new_thread(add_num, ('A',))  
    thread.start_new_thread(add_num, ('B',))  

if __name__== '__main__':  
    test()  

Python 在thread的幼功上还提供了贰个高等的线程序调整制库,就是以前涉嫌过的threading。Python的threading
module是在确立在thread module底蕴之上的三个module,在threading
module中,暴光了多数thread module中的属性。在thread
module中,python提供了客商级的线程同步工具“Lock”对象。而在threading
module中,python又提供了Lock对象的变种:
KugaLock对象。HighlanderLock对象内部维护着贰个Lock对象,它是后生可畏种可重入的靶子。对于Lock对象来讲,要是二个线程三番两次三次开展acquire操作,那么由于第三次acquire之后未有release,第一次acquire将挂起线程。那会变成Lock对象长久不会release,使得线程死锁。奥迪Q5Lock对象允许三个线程数十次对其实行acquire操作,因为在其里面通过三个counter变量维护着线程acquire的次数。并且每二回的acquire操作必须有三个release操作与之对应,在享有的release操作达成以后,别的线程本领报名该CRUISERLock对象。

上边来会见哪些使用threading的君越Lock对象达成合营。

import threading  
mylock = threading.RLock()  
num=0  

class myThread(threading.Thread):  
    def __init__(self, name):  
        threading.Thread.__init__(self)  
        self.t_name = name  

    def run(self):  
        global num  
        while True:  
            mylock.acquire()  
            print 'nThread(%s) locked, Number: %d'%(self.t_name, num)  
            if num>=4:  
                mylock.release()  
                print 'nThread(%s) released, Number: %d'%(self.t_name, num)  
                break  
            num+=1  
            print 'nThread(%s) released, Number: %d'%(self.t_name, num)  
            mylock.release()  

def test():  
    thread1 = myThread('A')  
    thread2 = myThread('B')  
    thread1.start()  
    thread2.start()  

if __name__== '__main__':  
    test()  

我们把校勘分享数据的代码成为“临界区”。必得将具备“临界区”都密封在同叁个锁对象的acquire和release之间。

2、  条件同步

锁只可以提供最大旨的一齐。假使只在爆发一些事件时才访谈八个“临界区”,那时候急需运用条件变量Condition。

Condition对象是对Lock对象的包裹,在创设Condition对象时,其结构函数需求三个Lock对象作为参数,若无这几个Lock对象参数,Condition就要里边自行创制叁个Odysseylock对象。在Condition对象上,当然也得以调用acquire和release操作,因为里面包车型客车Lock对象自己就扶助那几个操作。然则Condition的股票总值在于其提供的wait和notify的语义。

规格变量是怎么着行事的啊?首先贰个线程成功得到二个规范变量后,调用此标准变量的wait(State of Qatar方法会促成那么些线程释放这些锁,并进入“blocked”状态,直到另八个线程调用同一个规范变量的notify(State of Qatar方法来唤醒那个踏入“blocked”状态的线程。借使调用那么些标准变量的notifyAll(卡塔尔(قطر‎方法的话就能提示全部的在等候的线程。

只要程序照旧线程长久地处“blocked”状态以来,就能发生死锁。所以即便选拔了锁、条件变量等联手机制以来,应当要留意留意检查,幸免死锁景况的发生。对于大概爆发十一分的临界区要选择十一分管理体制中的finally子句来有限协助自由锁。等待四个规格变量的线程必需用notify(卡塔尔(قطر‎方法显式的提示,不然就长久沉默。保证每二个wait(卡塔尔方法调用都有二个相呼应的notify(卡塔尔(قطر‎调用,当然也得以调用notifyAll(State of Qatar方法防止万黄金年代。

 

 

坐褥者与买主难点是数黄金年代数二的一路难题。这里大概介绍二种差异的兑现情势。

1,  条件变量

import threading  

import time  

class Producer(threading.Thread):  

    def __init__(self, t_name):  

        threading.Thread.__init__(self, name=t_name)  



    def run(self):  

        global x  

        con.acquire()  

        if x > 0:  

            con.wait()  

        else:  

            for i in range(5):  

                x=x+1  

                print "producing..." + str(x)  

            con.notify()  

        print x  

        con.release()  



class Consumer(threading.Thread):  

    def __init__(self, t_name):  

        threading.Thread.__init__(self, name=t_name)  

    def run(self):  

        global x  

        con.acquire()  

        if x == 0:  

            print 'consumer wait1'  

            con.wait()  

        else:  

            for i in range(5):  

                x=x-1  

                print "consuming..." + str(x)  

            con.notify()  

        print x  

        con.release()  



con = threading.Condition()  

x=0  

print 'start consumer'  

c=Consumer('consumer')  

print 'start producer'  

p=Producer('producer')  



p.start()  

c.start()  

p.join()  

c.join()  

print x  

 

    上面的事例中,在始发状态下,Consumer处于wait状态,Producer接二连三临盆(对x试行增1操作)5次后,notify正在守候的Consumer。Consumer被唤醒伊始花费(对x执行减1操作) 

2,  同步队列

Python中的Queue对象也提供了对线程同步的支撑。使用Queue对象足以实现多少个分娩者和多少个客户造成的FIFO的行列。

劳动者将数据依次存入队列,消费者依次从队列中收取数据。

 

# producer_consumer_queue  

from Queue import Queue  

import random  

import threading  

import time  



#Producer thread  

class Producer(threading.Thread):  

    def __init__(self, t_name, queue):  

        threading.Thread.__init__(self, name=t_name)  

        self.data=queue  

    def run(self):  

        for i in range(5):  

            print "%s: %s is producing %d to the queue!n" %(time.ctime(), self.getName(), i)  

            self.data.put(i)  

            time.sleep(random.randrange(10)/5)  

        print "%s: %s finished!" %(time.ctime(), self.getName())  



#Consumer thread  

class Consumer(threading.Thread):  

    def __init__(self, t_name, queue):  

        threading.Thread.__init__(self, name=t_name)  

        self.data=queue  

    def run(self):  

        for i in range(5):  

            val = self.data.get()  

            print "%s: %s is consuming. %d in the queue is consumed!n" %(time.ctime(), self.getName(), val)  

            time.sleep(random.randrange(10))  

        print "%s: %s finished!" %(time.ctime(), self.getName())  



#Main thread  

def main():  

    queue = Queue()  

    producer = Producer('Pro.', queue)  

    consumer = Consumer('Con.', queue)  

    producer.start()  

    consumer.start()  

    producer.join()  

    consumer.join()  

    print 'All threads terminate!'  



if __name__ == '__main__':  

    main()  

在上边的事例中,Producer在放肆的大运内生产八个“付加物”,放入队列中。Consumer开掘队列中有了“成品”,就去花费它。本例中,由于Producer分娩的速度快于Consumer花费的快慢,所以反复Producer分娩许多少个“付加物”后,Consumer才开销三个成品。

Queue模块达成了二个支撑多producer和多consumer的FIFO队列。当分享消息须要安全的在十六线程之间沟通时,Queue极度实用。Queue的暗许长度是十二万分的,可是能够安装其构造函数的maxsize参数来设定其尺寸。Queue的put方法在队尾插入,该方法的原型是:

put( item[, block[, timeout]])

若果可选参数block为true何况timeout为None(缺省值),线程被block,直到队列空出一个数量单元。假设timeout大于0,在timeout的小时内,依然未有可用的多少单元,Full
exception被抛出。反之,若是block参数为false(忽视timeout参数),item被立马出席到空闲数据单元中,若无空余数据单元,Full
exception被抛出。

Queue的get方法是从队首取数据,其参数和put方法意气风发致。假若block参数为true且timeout为None(缺省值),线程被block,直到队列中有数量。假如timeout大于0,在timeout时间内,还是未有亮点数据,Empty
exception被抛出。反之,要是block参数为false(忽视timeout参数),队列中的数据被及时抽取。倘使此时不曾亮点数据,Empty
exception也会被抛出。

生龙活虎、Python中的线程使用:
Python中央银行使线程有三种办法:函数或许用类来包装线程对象。
1、函数式:调用th…

发表评论

电子邮件地址不会被公开。 必填项已用*标注