zoukankan      html  css  js  c++  java
  • Python并行编程(五):线程同步之信号量

    1、基本概念

          信号量是由操作系统管理的一种抽象数据类型,用于在多线程中同步对共享资源的使用。本质上说,信号量是一个内部数据,用于标明当前的共享资源可以有多少并发读取。

          同样在threading中,信号量有acquire和release两个函数。

          - 每当线程想要读取关联了信号量的共享资源时,必须调用acquire,此操作减少信号量的内部变量,如果此变量的值非负,那么分配该资源的权限。如果是负值,那么线程被挂起,直到有其他的线程释放资源。

          - 当线程不再需要该共享资源,必须通过release释放,这样,信号线的内部变量增加,在信号量等待队列中排在最前面的线程会拿到共享资源的权限。

          

          信号量同步机制在线程操作为原子操作时,才会没有问题,但如果不是原子操作,或者两个操作有一个终止了,就会出现问题,比如:

          有两个并发线程,都在等待一个信号量,假设目前信号量的内部值为1,再假设线程A将信号量的值从1减到0,此时线程A拿到资源权限,这时候如果控制器切换到了线程B,线程B将信号量的值从0减到-1,并且在这里被挂起等待,这时控制器回到线程A,信号量已经成为了负值,于是第一个线程也在等待。尽管当时的信号量是可以让线程访问资源的,但是因为非原子操作导致了所有的线程都在状态。

    2、信号量的使用

          使用信号量进行线程同步例子:

    # coding: utf-8
    import threading
    import time
    import random
    
    semaphore = threading.Semaphore(0)
    
    def consumer():
        print("Consumer is waiting.")
        semaphore.acquire()
        print("Consumer notify: Consumed item number %s" %item)
    
    def producer():
        global item
        time.sleep(10)
        item = random.randint(0, 100)
        print("Producer notify: Produced item number %s" %item)
        semaphore.release()
    
    if __name__ == "__main__":
        for i in range(0, 5):
            t1 = threading.Thread(target=producer)
            t2 = threading.Thread(target=consumer)
            t1.start()
            t2.start()
            t1.join()
            t2.join()
        print("Program terminated")

          信号量被初始化为0,semaphore = threading.Semaphore(0),目的是同步两个或多个线程。线程必须并行运行,所以需要信号量同步。

          如果信号量的计数器到了0,就会阻塞acquire方法,直到得到另一个线程的通知。如果信号量的计数器大于0,就会对这个值-1然后分配资源。

    3、补充

          信号量的一个特殊用法是互斥量。互斥量是初始值为1的信号量,可以实现数据、资源的互斥访问。

          信号量在支持多线程的编程语言中应用很广,但是他也有可能造成死锁的情况。例如,有一个线程t1,先等待信号量s1,然后等待信号量s2,而线程t2会先等待信号量s2,然后再等待信号量s1,这样就会发生死锁,导致t1等待s2,但是t2在等待s1。

  • 相关阅读:
    vagrantfile 示例
    服务器raid查看
    redis 使用记录
    golang 典型并发任务
    percona-server-mongodb 通用二进制下载
    命令之iperf-服务器之间网络测速
    用awk在命令行处理分析日志
    python是解释型还是编译型
    使用github action发布python包到Pypi
    算法图解学习系列--第6章--广度优先搜索算法BFS
  • 原文地址:https://www.cnblogs.com/dukuan/p/9771402.html
Copyright © 2011-2022 走看看