最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

Python多线程中线程间资源共享和常用的锁机制的介绍

来源:懂视网 责编:小采 时间:2020-11-27 14:20:41
文档

Python多线程中线程间资源共享和常用的锁机制的介绍

Python多线程中线程间资源共享和常用的锁机制的介绍:本篇文章给大家带来的内容是关于Python多线程中线程间资源共享和常用的锁机制的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。本文将简单介绍多线程编程中的线程间资源共享和常用的锁机制。在多线程编程中,常常会涉及到线程间的资源
推荐度:
导读Python多线程中线程间资源共享和常用的锁机制的介绍:本篇文章给大家带来的内容是关于Python多线程中线程间资源共享和常用的锁机制的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。本文将简单介绍多线程编程中的线程间资源共享和常用的锁机制。在多线程编程中,常常会涉及到线程间的资源

本篇文章给大家带来的内容是关于Python多线程中线程间资源共享和常用的锁机制的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

本文将简单介绍多线程编程中的线程间资源共享和常用的锁机制。

在多线程编程中,常常会涉及到线程间的资源共享, 常用资源共享常用方式:

  • 全局变量(global)

  • queue(from queue import Queue)

  • 常用的资源共享锁机制:

  • Lock

  • RLock

  • Semphore

  • Condition

  • (一) 线程间资源共享

    1. 使用全局变量可以实现线程间的资源共享,关键字global

    代码演示:

    from threading import Thread, Lock
    lock = Lock()
    total = 0
    
    '''如果不使用lock那么,最后得到的数字不一定为0;同时loack不支持连续多次acquire,如果这样做了的后果是死锁!'''
    def add():
     global total
     global lock
     for i in range(1000000):
     lock.acquire()
     total += 1
     lock.release()
     
    def sub():
     global total
     global lock
     for i in range(1000000):
     lock.acquire()
     total -= 1
     lock.release()
     
    thread1 = Thread(target=add)
    thread2 = Thread(target=sub)
    
    
    # 将Thread1和2设置为守护线程,主线程完成时,子线程也一起结束
    # thread1.setDaemon(True)
    # thread1.setDaemon(True)
    
    # 启动线程
    thread1.start()
    thread2.start()
    
    # 阻塞,等待线程1和2完成,如果不使用join,那么主线程完成后,子线程也会自动关闭。
    thread1.join()
    thread2.join()
    
    total
    1. 使用queue共享资源,queue是线程安全的。

    from threading import Thread, Lock
    from queue import Queue
    
    def add(q):
     if q.not_full:
     q.put(1)
     
    def sub(q):
     if q.not_empty:
     recv = q.get()
     print(recv)
     q.task_done()
     
    if __name__ =='__main__':
     # 设置q最多接收3个任务,Queue是线程安全的,所以不需要Lock
     qu = Queue(3)
     thread1 = Thread(target=add, args=(qu,))
     thread2 = Thread(target=sub, args=(qu,))
     thread1.start()
     thread2.start()
     # q队列堵塞,等待所有任务都被处理完。
     qu.join()

    (二) 锁(Lock/RLock/Condition/Semphore)

    1. Lock

    Lock 不能连续acquire锁,不然会死锁,Lock 资源竞争可能会导致死锁。

    Lock 会降低性能。

    from threading import Thread, Lock
    lock = Lock()
    total = 0
    
    '''如果不使用lock那么,最后得到的数字不一定为0;同时lock不支持连续多次acquire,如果这样做了的后果是死锁!'''
    def add():
     global total
     global lock
     for i in range(1000000):
     lock.acquire()
     total += 1
     lock.release()
     
    def sub():
     global total
     global lock
     for i in range(1000000):
     lock.acquire()
     total -= 1
     lock.release()
     
    thread1 = Thread(target=add)
    thread2 = Thread(target=sub)
    
    # 将Thread1和2设置为守护线程,主线程完成时,子线程也一起结束
    # thread1.setDaemon(True)
    # thread1.setDaemon(True)
    
    # 启动线程
    thread1.start()
    thread2.start()
    
    # 阻塞,等待线程1和2完成,如果不使用join,那么主线程完成后,子线程也会自动关闭。
    thread1.join()
    thread2.join()
    total
    1. RLock

    RLock 可以连续acquire锁,但是需要相应数量的release释放锁

    因可以连续获取锁,所以实现了函数内部调用带锁的函数

    from threading import Thread, Lock, RLock
    lock = RLock()
    total = 0
    def add():
     global lock
     global total
     # RLock实现连续获取锁,但是需要相应数量的release来释放资源
     for i in range(1000000):
     lock.acquire()
     lock.acquire()
     total += 1
     lock.release()
     lock.release()
    def sub():
     global lock
     global total
     for i in range(1000000):
     lock.acquire()
     total -= 1
     lock.release()
    thread1 = Thread(target=add)
    thread2 = Thread(target=sub)
    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()
    total
    1. Condition 条件变量

    Condition条件变量服从上下文管理协议:使用with语句获取封闭块持续时间的关联锁。

    wait()方法释放锁,然后阻塞,直到另一个线程通过调用notify()或notify_all()唤醒它。一旦被唤醒,wait()重新获得锁并返回。也可以指定超时。

    先启动wait接收信号的函数,处于阻塞等待状态,再启动notify的函数发出信号

    from threading import Thread, Condition
    '''聊天
     Peaple1 : How are you?
     Peaple2 : I`m fine, thank you!
     
     Peaple1 : What`s your job?
     Peaple2 : My job is teacher.
     
    '''
    
    def Peaple1(condition):
     with condition:
     print('Peaple1 : ', 'How are you?')
     condition.notify()
     condition.wait()
     
     print('Peaple1 : ', 'What`s your job?')
     condition.notify()
     condition.wait()
    
    def Peaple2(condition):
     with condition:
     condition.wait()
     print('Peaple2 : ', 'I`m fine, thank you!')
     condition.notify()
     
     condition.wait()
     print('Peaple2 : ', 'My job is teacher.')
     condition.notify()
    
    
    if __name__ == '__main__':
     cond = Condition()
     thread1 = Thread(target=Peaple1, args=(cond,))
     thread2 = Thread(target=Peaple2, args=(cond,))
     
     # 此处thread2要比thread1提前启动,因为notify必须要有wait接收;如果先启动thread1,没有wait接收notify信号,那么将会死锁。
     thread2.start()
     thread1.start()
    
    # thread1.join()
    # thread2.join()
    1. Semphore

    该类实现信号量对象。信号量管理一个原子计数器,表示release()调用的数量减去acquire()调用的数量加上一个初始值。如果需要,acquire()方法会阻塞,直到它可以返回而不使计数器为负。如果没有给出,则值默认为1。

    #Semaphore 是用于控制进入数量的锁
    #文件, 读、写, 写一般只是用于一个线程写,读可以允许有多个
    
    import threading
    import time
    
    class HtmlSpider(threading.Thread):
     def __init__(self, url, sem):
     super().__init__()
     self.url = url
     self.sem = sem
    
     def run(self):
     time.sleep(2)
     print("Download {html} success
    ".format(html=self.url))
     self.sem.release()
    
    class UrlProducer(threading.Thread):
     def __init__(self, sem):
     super().__init__()
     self.sem = sem
    
     def run(self):
     for i in range(20):
      self.sem.acquire()
      html_thread = HtmlSpider("https://www.baidu.com/{}".format(i), self.sem)
      html_thread.start()
    
    if __name__ == "__main__":
     # 控制锁的数量, 每次同时会有3个线程获得锁,然后
    输出 sem = threading.Semaphore(3) url_producer = UrlProducer(sem) url_producer.start()

    (三)简单介绍多进程编程

    1. 多进程编程中进程间不能实现全局变量共享,也不能使用queue.Queue

    2. 多进程编程通信需要使用Queue,Pipe

    3. 如果使用进程池进程编程需要使用Manger的实例的queue来实现通信

    声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文档

    Python多线程中线程间资源共享和常用的锁机制的介绍

    Python多线程中线程间资源共享和常用的锁机制的介绍:本篇文章给大家带来的内容是关于Python多线程中线程间资源共享和常用的锁机制的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。本文将简单介绍多线程编程中的线程间资源共享和常用的锁机制。在多线程编程中,常常会涉及到线程间的资源
    推荐度:
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top