python多线程3线程同步

#coding:gbk
'''
Created on 2013-1-5

@author: Jimmy

@note: Lock, RLock, Semaphore, Condition, Event and Queue
                只是介绍怎么初始化和使用,完整代码可见MThread中的同步操作
'''

import threading
import Queue
if __name__ == "__main__":
    phone = 0
    '''
    A、多个线程使用同一个Lock, RLock, Semaphore, Condition, Event and Queue的对象;
            Lock, RLock, Semaphore是线程操作临界区的互斥方法;
            Event是线程间同步的方法
    B、Lock,RLock,Semaphore(锁和信号)其中个人觉得使用RLock比较好,Lock和Semaphore是比较老,不在推荐使用了;
    C、Event有点复杂,有一个完整的例子在ThreadSynchronizationTest.py中;解释了Clear()的作用和控制特定的
    D、Condition算是 Lock 和 Event 的杂交版本;
    
    '''
    #1、锁:threading.Lock,threading.RLock的使用相同;不同点是Lock会死锁,RLock不会(Lock两次acquire,就死锁了;相反,RLock不会)
    lock = threading.Lock()#lock = threading.RLock()
    lock.acquire()#锁获取
    phone += 1#互斥操作
    lock.release()#释放锁
    
    #2、信号:threading.Semaphore(是比较老的一种同步互斥方法,pv操作;Semaphore的api和锁api一样;信号不会<0
    sem = threading.Semaphore()#初始化信号为1
    sem.acquire()#信号减1
    phone += 1#互斥操作
    sem.release()#信号加1
    
    #3、事件:threading.Event
    '''
            其实threading.Event和RLock、Lock和Semaphore使用场景是不同的。
     Event是线程间协调同步的操作。一个线程wait()挂起等待某个资源(由另外一个线程控制);另外一个线程完成后操作Set()
     RLock是同一个线程中成对使用的,控制只有一个线程在一个时间操作临界资源
     
    AAAA注:Set()后,所有的线程都会收到;要想只用一个线程获取到,要加Clear()操作
         Clear()方法是比较重要的,要想只有一个线程获取信号,在wait()或者Set()操作后要Clear()下。
             Set()后调用Clear()一定只有一个线程获取,Wait()后调用Clear()不一定(因为,不一定是该线程第一个执行)
    '''
    event = threading.Event()
    event.wait()#线程1
    event.set()#线程2
    event.clear()#线程2
    
    #3、事件:threading.Condition
    cond = threading.Condition()
    #RLock的属性
    cond.acquire()
    cond.release()
    #Event的属性
    cond.wait()#Wait until notified
    cond.notify()#Wake up a thread waiting on this condition
    cond.notifyAll()#Wake up all threads  ==notify_all()
    
    #threading.Queue
    '''
        Queue模块实现了一个支持多producer和多consumer的FIFO队列。当共享信息需要安全的在多线程之间交换时,Queue非常有用。
    Queue的默认长度是无限的, 但是可以设置其构造函数的maxsize参数来设定其长度。
    put:
        Queue的put方法在队尾插入,该方法的原型是:put( item[, block[, timeout]])
         如果可选参数block为true并且timeout为None(缺省值),线程被block,直到队列空出一个数据单元。如果timeout大于0,在timeout的时间内,仍然没有可用的数据单元,
    Full exception被抛出。反之,如果block参数为false(忽略timeout参数),item被立即加入到空闲数据单元中,如果没有空闲数据单元,Full exception被抛出。
    get:
        Queue的get方法是从队首取数据,其参数和put方法一样。如果block参数为true且timeout为None(缺省值),线程被block,直到队列中有数据。
         如果timeout大于0,在timeout时间内,仍然没有可取数据,Empty exception被抛出。
         反之,如果block参数为false(忽略timeout参数),队列中的数据被立即取出。如果此时没有可取数据,Empty exception也会被抛出。
         Queue.join() 实际上意味着等到队列为空,再执行别的操作
    '''
    queue = Queue.Queue()
    queue.get()#获取
    queue.put()#插入
    pass
  

  

原文地址:https://www.cnblogs.com/2012harry/p/2845277.html