zoukankan      html  css  js  c++  java
  • Python多线程学习笔记

    Python中与多线程相关的模块有 thread, threading 和 Queue等,thread 和threading模块允许程序员创建和管理线程。thread模块提供了基本的线程和锁的支持,而threading提供了更高级别,功能更强的线程管理的功能。Queue 模块允许用户创建一个可以用于多个线程之间共享数据的队列数据结构。一般不建议用thread模块。

    1.threading模块

    threading 模块对象函数       描述
    Thread           表示一个线程的执行的对象
    Lock             锁原语对象(跟 thread 模块里的锁对象相同)
    RLock             可重入锁对象。使单线程可以再次获得已经获得了的锁(递归锁定)。
    Condition           条件变量对象能让一个线程停下来,等待其它线程满足了某个“条件”。如,状态的改变或值的改变。
    Event             通用的条件变量。多个线程可以等待某个事件的发生,在事件发生后,所有的线程都会被激活。
    Semaphore           为等待锁的线程提供一个类似“等候室”的结构
    BoundedSemaphore 与 Semaphore 类似,只是它不允许超过初始值

    Timer与 Thread 相似,只是,它要等待一段时间后才开始运行。

    threading 模块的其他函数
    函数         描述
    activeCount()     当前活动的线程对象的数量
    currentThread()    返回当前线程对象
    enumerate()     返回当前活动线程的列表
    settrace(func)     为所有线程设置一个跟踪函数
    setprofile(func)  a为所有线程设置一个 profile 函数

    Thread 对象的函数
    函数         描述
    start()         开始线程的执行
    run()         定义线程的功能的函数(一般会被子类重写)
    join(timeout=None)   程序挂起,直到线程结束;如果给了 timeout,则最多阻塞 timeout 秒
    getName()       返回线程的名字
    setName(name)     设置线程的名字
    isAlive()         布尔标志,表示这个线程是否还在运行中
    isDaemon()       返回线程的 daemon 标志
    setDaemon(daemonic)  把线程的 daemon 标志设为 daemonic(一定要在调用 start()函数前调用)

    import threading
    from time import sleep,ctime
    def loop1():
        print "loop1 start  at",ctime()
        sleep(4)
        print "loop1 end at",ctime()
    def loop2():
        print "loop2 start at",ctime()
        sleep(6)
        print "loop2 end at ",ctime()
    t1=threading.Thread(target=loop1)
    t2=threading.Thread(target=loop2)
    t1.start()
    t2.start()

    输出结果:

    2.通过Lock实现线程同步

    #encoding=utf-8
    import threading
    from time import sleep,ctime
    mylock=threading.RLock()  # 实例化一个RLock对象,注意L是大写的
    left=10 def loop1(tid): global left while 1: mylock.acquire() if left>0: sleep(1) left=left-1 print str(left)+" tickets left i am thread"+str(tid) mylock.release() t1=threading.Thread(target=loop1,args=("1")) t2=threading.Thread(target=loop1,args=("2")) t3=threading.Thread(target=loop1,args=("3")) t1.start() t2.start() t3.start()

    3.继承thead.Tread类实现多线程

    #encoding=utf-8
    import threading
    from time import sleep,ctime
    mylock=threading.RLock()  # 实例化一个RLock对象,注意L是大写的
    left=10
    class MyThread(threading.Thread):
        def __init__(self,tid):
            threading.Thread.__init__(self)
            self.tid=tid
        def run(self):
            global left
            while 1:
                mylock.acquire()
                if left>0:
                    sleep(1)
                    left=left-1
                    print str(left)+" tickets left  i am thread"+str(self.tid)
                mylock.release()
    
    t1=MyThread("1")
    t2=MyThread("2")
    t3=MyThread("3")
    t1.start()
    t2.start()
    t3.start()

    4.Queue模块

    函数               描述
    Queue 模块函数
    queue(size)           创建一个大小为 size 的 Queue 对象

    Queue 对象函数
    qsize()             返回队列的大小(由于在返回的时候,队列可能会被其它线程修改,所以这个值是近似值)
    empty()             如果队列为空返回 True,否则返回 False
    full()               如果队列已满返回 True,否则返回 False
    put(item,block=0)        把 item 放到队列中,如果给了 block(不为 0),函数会一直阻塞到队列中有空间为止
    get(block=0)           从队列中取一个对象,如果给了 block(不为 0),函数会一直阻塞到队列中有对象为止

    #encoding=utf-8
    import threading
    import random
    from time import sleep,ctime
    from Queue import  Queue
    myQueue=Queue()
    class Product(threading.Thread):
        def __init__(self,queue):
            threading.Thread.__init__(self)
            self.queue=queue
        def run(self):
            itemID=1
            for i in range(10):
                sleep(2)
                self.queue.put("item"+str(itemID))
                print "product item",itemID
                itemID=itemID+1
    class Consume(threading.Thread):
        def __init__(self,queue):
            threading.Thread.__init__(self)
            self.queue=queue
        def run(self):
            itemID=1
            while 1:
                
                sleep(random.random()*5)
                if  not self.queue.empty():
                    item=self.queue.get()
                    print "consume ",item
                else:
                    print "DONE"
                    break
            
                
    productT=Product(myQueue)
    consumeT=Consume(myQueue)
    productT.start()
    consumeT.start()

    5.使用Queue实现多线程数量控制

    #encoding=utf-8
    __author__ = 'kevinlu1010@qq.com'
    import threading
    from time import sleep
    from Queue import Queue
    q=Queue(5)
    
    def f(num):
        print num
        sleep(1)
        q.get()
    for i in range(10):
        q.put(1,block=1)
        p=threading.Thread(target=f,args=[i])
        p.start()

    这里主要应用了Queue put时可以阻塞的特性来实现线程数的控制

    6.高级版:利用线程池和map实现多线程

    #encoding=utf-8
    __author__ = 'kevinlu1010@qq.com'
    from time import sleep
    from multiprocessing.dummy import Pool as ThreadPool
    
    pool =ThreadPool(4)  #线程池的大小,总并发数
    def f(a):
        print 'hello%s'%str(a)
        sleep(1)
        
    b=pool.map(f,range(10))
    # pool.close()
    # pool.join()
    print 'hello  last'

    用到了 multiprocessing 里面的 Pool类,实现起来非常方便,而且效率很高。

    参考:http://www.oschina.net/translate/python-parallelism-in-one-line

  • 相关阅读:
    Annotation
    GIT的作用以及Versioncontrol为什么要用GIT
    Http协议
    人工智能的可怕与不可怕
    Makefile简易教程
    Node.js 学习笔记之一:学习规划 & 认知 Node.js
    《大教堂与集市》的启示 — 软件工程的另一种选择
    Git简易教程
    谈谈买书与读书
    clang编译器简介
  • 原文地址:https://www.cnblogs.com/Xjng/p/3514518.html
Copyright © 2011-2022 走看看