zoukankan      html  css  js  c++  java
  • Python之多线程:线程互斥与线程同步

    一、锁在多线程中的使用:线程互斥
    lock = threading.Lock()#创建一个锁对象
    1、with lock:
    pass
    和进程使用的方式相同
     
    2、控制线程结束的时间
    通过一个全局变量
    # encoding=utf-8
    import threading,time,Queue,random
     
    exitFlag = False
    def write(lock,queue):
    while exitFlag != True:
    with lock:
    data = random.randint(1,100)
    print 'put:',data
    queue.put(data)
    time.sleep(1)
     
    def read(queue):
    while exitFlag != True:
    print 'get:',queue.get()
    time.sleep(1)
     
    if __name__ == '__main__':
    lock = threading.Lock()
    queue = Queue.Queue()
    t1 = threading.Thread(target=write,args=(lock,queue))
    t2 = threading.Thread(target=write,args=(lock,queue))
    t3 = threading.Thread(target=read,args=(queue,))
    t1.start()
    t2.start()
    t3.start()
    time.sleep(10)
    exitFlag = True
    t1.join()
    t2.join()
    t3.join()
     
    二、线程同步
    1、生产者--消费者模式
    Queue() 作为生产者和消费者的中介
    from
     
    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 xrange(5):
    print '%s:%s is producing %d to the queue '%(time.ctime(),self.getname(),i)
    self.data.put(i)
    time.sleep(2)
    print '%s:%s put finished '%(time.ctime(),self.getname(),i)
    def 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 xrange(5):
    val=self.data.get()
    print '%s:%s is consumer %d in the queue '%(time.ctime(),self.getname(),val)
    print '%s:%s consumer finished '%(time.ctime(),self.getname(),i)
     
    if __name=='__main__':
    queue=Queue()#没有制定队列大小,默认为无限大,可以不受限制的放入队列
    producer=Producer('Pro',queue)
    consumer=Consumer('Con',queue)
    producer.start()
    time.sleep(1)
    consumer.start()
    producer.join()
    consumer.join()
    print 'mainThread end'
     
    2、Event 信号传递
    event=threading.Event()
    import threading,time,Queue,random
     
    def write(lock,queue,event):
    while not event.isSet():
    with lock:
    thread = threading.currentThread()
    data = random.randint(1,100)
    print 'this is thread:',thread.getName(),'put:',data
    queue.put(data)
    time.sleep(1)
     
    def read(queue):
    while not event.isSet():
    print 'get:',queue.get()
    time.sleep(1)
     
    if __name__ == '__main__':
    lock = threading.Lock()
    queue = Queue.Queue()
    event=threading.Event()
    t1 = threading.Thread(target=write,args=(lock,queue,event))
    t2 = threading.Thread(target=write,args=(lock,queue,event))
    t3 = threading.Thread(target=read,args=(queue,))
    t1.start()
    t2.start()
    t3.start()
    time.sleep(10)
    event.set()
    t1.join()
    t2.join()
    t3.join()
    3、lock :只能加一把锁
    4、semaphore:可以加多把锁
    设置限制最多3个线程同时访问共享资源:s = threading.Semaphore(3)
    5、event:线程等待某一时间的发生,之后执行逻辑
    6、Condition 条件
    con=threading.Condition()
    使用场景:处理复杂的逻辑。基于锁来实现的
    两个线程之间做一些精准的通信
    线程A做了某一件事,中途需要停止
    线程B做另外一件事情,线程B通知线程A
    线程A继续
    (1)额外提供了wait()方法和notify()方法,用于处理复杂的逻辑
    (2)wait()释放锁,并且等待通知
    (3)Notify()唤醒对方,可以继续下去。但是需要两个线程之间需要抢锁,谁抢到执行谁
    通过(2)和(3),实现线程间的通信。
    import threading
    import time
    product = 0
    exitFlag = False
    def consumer(con):
    global product
    while exitFlag != True:
    with con:
    print 'enter consummer thread'
    if product == 0:
    con.wait()
    else:
    print 'now consummer 1 product'
    product -= 1
    print 'after consummer, we have ',product,'product now'
    time.sleep(2)
     
    def producer(con):
    global product
    while exitFlag != True:
    with con:
    print 'enter producer thread'
    product += 1
    con.notify()
    print 'after producer, we have ', product, 'product now'
    time.sleep(2)
     
    if __name__ == '__main__':
    con = threading.Condition()
    c1 = threading.Thread(target=consumer,args=(con,))
    p1 = threading.Thread(target=producer, args=(con,))
     
    c1.start()
    p1.start()
    time.sleep(6)
    exitFlag = True
    c1.join()
    p1.join()
     
    7、死锁
    t1:拥有lock1锁,申请lock2锁
    t2:拥有lock2锁,申请lock1锁
    (1)如何尽量的保证不出现死锁:
    定义锁的使用顺序
  • 相关阅读:
    4Sum
    3Sum Closest
    3Sum
    Longest Common Prefix
    Roman to Integer
    thinkphp3.2自定义配置文件
    centos7下git的使用和配置
    git 报错
    Git服务器安装详解及安装遇到问题解决方案
    centos GIT安装
  • 原文地址:https://www.cnblogs.com/emily-qin/p/7210922.html
Copyright © 2011-2022 走看看