• 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)如何尽量的保证不出现死锁:
    定义锁的使用顺序
  • 相关阅读:
    leetcode 122. Best Time to Buy and Sell Stock II
    leetcode 121. Best Time to Buy and Sell Stock
    python 集合(set)和字典(dictionary)的用法解析
    leetcode 53. Maximum Subarray
    leetcode 202. Happy Number
    leetcode 136.Single Number
    leetcode 703. Kth Largest Element in a Stream & c++ priority_queue & minHeap/maxHeap
    [leetcode]1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree
    正则表达式
    十种排序算法
  • 原文地址:https://www.cnblogs.com/emily-qin/p/7210922.html
Copyright © 2020-2023  润新知