• Python threading(多线程)


       threading模块在较低级别thread模块之上构建更高级别的线程接口。

    一、threading模块定义了以下函数和对象:

      threading.active_count()
        等同于threading.activeCount(),返回Thread当前活动的对象数。返回的计数等于返回的列表的长度enumerate()。

      threading.Condition()
        返回新条件变量对象的工厂函数。条件变量允许一个或多个线程等待,直到另一个线程通知它们。

      threading.current_thread()
        等同于currentThread(),返回当前Thread对象,对应于调用者的控制线程。如果未通过threading模块创建调用者的控制线程,则返回具有有限功能的虚拟线程对象。

      threading.enumerate()
        返回Thread当前活动的所有对象的列表。该列表包括守护线程,由其创建的虚拟线程对象 current_thread()和主线程。它排除了尚未启动的已终止线程和线程。

      threading.Event()
        返回新事件对象的工厂函数。事件管理一个标志,该标志可以使用该set()方法设置为true,并使用该方法重置为false clear()。该wait()方法将阻塞,直到该标志为真。

      class threading.local
        表示线程本地数据的类。线程局部数据是其值是线程特定的数据。要管理线程本地数据,只需创建一个local(或子类)实例并在其上存储属性。

      threading.Lock()
        返回新原始锁定对象的工厂函数。一旦线程获得它,后续尝试获取它就会阻塞,直到它被释放; 任何线程都可以释放它。

      threading.RLock()
        返回新的可重入锁定对象的工厂函数。必须由获取它的线程释放可重入锁。一旦线程获得了可重入锁,同一个线程可以再次获取它而不会阻塞; 线程必须在每次获取它时释放一次。

      threading.Semaphore([ value] )
        返回新信号量对象的工厂函数。信号量管理一个计数器,表示release()呼叫数减去acquire()呼叫数 加上初始值。该acquire()方法在必要时阻止,直到它可以返回而不使计数器为负。如果没有给出,则值默认为1。

      threading.BoundedSemaphore([ value] )
        返回新的有界信号量对象的工厂函数。有界信号量检查以确保其当前值不超过其初始值。如果确实如此,ValueError则提出。在大多数情况下,信号量用于保护容量有限的资源。如果信号量被释放太多次,则表明存在错误。如果没有给出,则值默认为1。

      class threading.Thread
        表示控制线程的类。该类可以以有限的方式安全地进行子类化。

      class threading.Timer
        在指定的时间间隔过后执行函数的线程。

      threading.settrace(func
        为从threading模块启动的所有线程设置跟踪功能。在调用sys.settrace()其run()方法之前,将为每个线程 传递 func。

      threading.setprofile(func
        为从threading模块启动的所有线程设置配置文件功能。在调用sys.setprofile()其run()方法之前,将为每个线程 传递 func。

      threading.stack_size([ size] )
        返回创建新线程时使用的线程堆栈大小。可选的 size参数指定用于后续创建的线程的堆栈大小,并且必须为0(使用平台或配置的默认值)或至少为32,768(32 KiB)的正整数值。

        如果未指定大小,则使用0。如果不支持更改线程堆栈大小,则引发ThreadError。如果指定的堆栈大小无效,则引发ValueError 且堆栈大小不被修改。32kB是目前支持的最小堆栈大小值,以保证解释器本身有足够的堆栈空间。

        请注意,某些平台可能对堆栈大小的值有特定限制,例如要求最小堆栈大小> 32kB或需要以系统内存页面大小的倍数进行分配 - 应参考平台文档以获取更多信息(4kB页面是常见的 ;在没有更具体的信息的情况下,建议的方法是使用4096的倍数作为堆栈大小。

      exception threading.ThreadError
        针对各种与线程相关的错误引发。请注意,许多接口使用RuntimeError而不是ThreadError。

    二、Thread Objects

      此类表示在单独的控制线程中运行的活动,有两种方法可以指定活动:

      一是将可调用对象传递给构造函数,二是通过覆盖子类中的run()方法,但不要在子类中重写其他方法,换句话说,只覆盖此类的__init __()和run()方法。

      classthreading.Threadgroup = None,target = None,name = None,args =(),kwargs = {}

        应始终使用关键字参数调用此构造函数。参数是:

          group 应该None,在实现ThreadGroup类时保留用于将来的扩展。

          target 是run()方法调用的可调用对象。默认为None,意味着什么都没有被调用。

          name 是线程名称。默认情况下,唯一名称由“Thread- N ” 形式构成,其中N是小十进制数。

          args 是目标调用的参数元组。默认为()。

          kwargs 是目标调用的关键字参数字典。默认为{}。

        如果子类重写构造函数,则必须确保在对线程执行任何其他操作之前调用基类构造函数(Thread .__ init __())。

      start()
        启动线程的活动。

        每个线程对象最多只能调用一次,它安排在一个单独的控制线程中调用对象的 run()方法。

        如果在同一个线程对象上多次调用此方法,则会引发RuntimeError。

      run()
        表示线程活动的方法。

        你可以在子类中覆盖此方法。 标准的 run()方法调用传递给对象构造函数的可调用对象作为目标参数,分别使用args和kwargs参数中的顺序和关键字参数。

      join([ timeout] )
        等待线程终止,这将阻塞调用线程,直到调用其join()方法的线程终止,或者直到发生异常、超时。

        当timeout参数存在且非None时,它应该是一个浮点数,用于指定操作的超时(以秒为单位);反之当timeout参数不存在或为None时,操作将阻塞直到线程终止。

        由于join()总是返回None,你必须在join()之后调用isAlive()来判断是否发生了超时,如果线程仍处于活动状态,则join()调用超时。

        如果在线程启动之前调用join(),则会引发RuntimeError。

      name()
        一个仅用于识别目的字符串,它没有语义。 多个线程可以赋予相同的名称,初始名称由构造函数设置。

        getName()
        setName()

      ident

        该线程的标识符,如果线程尚未启动,则为None,这是一个非零整数。当线程退出并创建另一个线程时,线程标识符可以被回收。 即使在线程退出后,该标识符也可用。

      is_alive()
        等同于isAlive(),返回线程是否存活。

        此方法在run()方法启动之前返回True,直到run()方法终止之后。 模块函数enumerate()返回所有活动线程的列表。

      daemon()
        一个布尔值,指示此线程是否为守护程序线程True 或False。 必须在调用start()之前设置它,否则引发RuntimeError。 它的初始值继承自创建线程,主线程不是守护程序线程,因此在主线程中创建的所有线程都默认为daemon = False。

        isDaemon()
        setDaemon()

    三、Lock Objects

      原始锁是一种同步原语,在锁定时不属于特定线程。 在Python中,它是当前可用的最低级别同步原语,由线程扩展模块直接实现。

      Lock.acquire([ blocking] )
        获取锁定,blocking或non-blocking。

        当blocking参数设置为True 时调用(默认值),阻塞直到解锁,然后将其设置为锁定并返回True。

        在将blocking参数设置为False的情况下调用时,请勿阻止。如果blocking设置为True的调用将阻塞,则立即返回False;否则,将Lock设置为锁定并返回True。

      Lock.release()
        释放锁定。

        当Lock是锁定时,将其重置为解锁状态,然后返回。如果阻止任何其他线程等待Lock解锁,则只允许其中一个继续执行。

        在未锁定的Lock上调用时,会引发ThreadError。

        

    四、RLock Objects

      线程会调用其acquire()方法来锁定Lock,调用其release()方法来解锁Lock,一旦线程拥有Lock它就会返回。

      acquire()/release()可以嵌套调用,只有最终的release()将Lock重置为unlocked并允许在acquire()中阻塞的另一个线程继续进行。

      RLock.acquire([ blocking = 1 ] )
        获取锁定,blocking或non-blocking。

        在不带参数的情况下调用:如果此线程已拥有锁,则将递归级别递增1,并立即返回。否则,如果另一个线程拥有该锁,则阻塞直到锁被解锁。

        Lock解锁后(不属于任何线程),然后获取所有权,将递归级别设置为1,然后返回。如果多个线程被阻塞等待Lock解锁,则一次只能有一个线程获取Lock的所有权。在这种情况下没有返回值。

        在将blocking参数设置为true的情况下调用时,执行与不带参数调用时相同的操作,并返回true。

        在将blocking参数设置为false的情况下调用时,请勿阻止。如果没有参数的调用会阻塞,则立即返回false;否则,执行与不带参数调用时相同的操作,并返回true。

      RLock.release()
        释放锁定,递减递归级别。如果在递减之后它为零,则将Lock重置为未锁定,并且如果阻止任何其他线程等待Lock解锁,则允许其中一个继续进行。如果在递减之后递归级别仍然非零,则Lock保持锁定并由调用线程拥有。

        仅在调用线程拥有Lock时调用此方法。如果在未锁定时调用此方法,则引发RuntimeError。

    五、Condition Objects

      该类总是与某种锁相关联,默认情况下会创建一个,也可以传入。

      该类具有acquire()和release()方法,这些方法调用相关锁的相应方法。它还有一个wait()方法,以及notify()和notifyAll()方法,只有在调用线程获得锁定时才能调用这三个,否则会引发RuntimeError。

      class threading.Condition([ lock ] )
        如果给出lock参数且非None,则它必须是一个Lock 或RLock对象,并且它被用作底层锁。否则,将创建一个RLock新对象并将其用作基础锁。

      acquire(* args )
        获取底层锁。此方法在底层锁上调用相应的方法; 返回该方法所有值。

      release()
        释放底层锁。此方法在底层锁上调用相应的方法; 没有返回值。

      wait([timeout] )
        等到通知或直到发生超时。如果在调用此方法时调用线程尚未获取锁定,则引发RuntimeError。

        此方法释放底层锁,然后阻塞直到它被另一个线程中的相同条件变量的notify()或notifyAll()调用唤醒,或者直到发生超时。一旦被唤醒或超时,它就会重新获得锁定并返回。

        当timeout参数存在且非None时,它应该是一个浮点数,指定操作的超时(以秒为单位)。

        当底层锁是一个RLock时,它不会使用其release()方法释放,因为当递归多次获取时,这实际上可能无法解锁。相反,使用了RLock类的内部接口,即使多次递归获取也能解锁它。然后,在重新获取锁时,使用另一个内部接口来恢复递归级别。

      notify(n = 1 )
        默认情况下,唤醒一个等待此条件的线程。如果在调用此方法时调用线程尚未获取锁定, 则引发RuntimeError。

        此方法最多唤醒等待条件变量的n个线程,如果没有线程在等待,那么这是一个无用操作。

      notify_all()
        等同于notifyAll(),唤醒符合条件的所有等待线程。此方法就像 notify(),但唤醒所有等待的线程而不是一个。如果在调用此方法时调用线程尚未获取锁定, 则引发RuntimeError。

    # Consume one item
    cv.acquire()
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()
    cv.release()
    
    # Produce one item
    cv.acquire()
    make_an_item_available()
    cv.notify()
    cv.release()

    六、Semaphore Objects

      Semaphore管理一个内部计数器,该计数器由每个acquire()调用递减,并由每个release()调用递增。 计数器永远不会低于零,当acquire()发现它为零时,它会阻塞,等待其他线程调用release()。

      class threading.Semaphore([ value ] )
        可选参数给出内部计数器一个初始value; 它默认为1。如果给定的值小于0,则引发ValueError。

      acquire([ block] )
        获取信号量。

        在不带参数的情况下调用:如果内部计数器在输入时大于零,则将其减1并立即返回。如果在进入时为零,则阻塞,等待其他线程调用 release()以使其大于零。

        这是通过适当的互锁来完成的,这样如果多个acquire()呼叫被阻止,它们 release()将完全唤醒其中一个。实现可以随机选择一个,因此不应该依赖被阻塞的线程被唤醒的顺序。在这种情况下没有返回值。

        当使用blocking设置为true 调用时,执行与不带参数调用时相同的操作,并返回true。

        当阻塞设置为false 时调用,请勿阻止。如果没有参数的调用会阻塞,则立即返回false; 否则,执行与不带参数调用时相同的操作,并返回true。

      release()
        释放信号量,将内部计数器递增1。当它在进入时为零并且另一个线程正在等待它再次大于零时,唤醒该线程。

    七、Event Objects

      可以使用set()方法将其标志设置为true,并使用clear()方法将其标志重置为false,wait()方法将阻塞,直到该标志为true。

      class threading.Event
        内部标志初始为false。

      is_set()
      isSet()
        当且仅当内部标志为真时返回true。

      set()
        将内部标志设置为true。等待它变为真的所有线程都被唤醒。wait()一旦标志为真,调用的线程将不会阻塞。

      clear()
        将内部标志重置为false。随后,线程调用 wait()将阻塞,直到set()被调用以再次将内部标志设置为true。

      wait([ timeout] )
        阻止,直到内部标志为真。如果输入时内部标志为真,则立即返回。否则,阻塞直到另一个线程调用 set()将标志设置为true,或者直到发生超时。

        当timeout参数存在且非None时,它应该是一个浮点数,指定操作的超时(以秒为单位)。

        此方法在退出时返回内部标志,因此它将始终返回True, 除非给定超时并且操作超时。

         

    八、Timer Objects

       通过调用start()方法启动计时器,通过调用cancel()方法可以停止计时器(在其动作开始之前)。

      class threading.Timer(interval,function,args = [],kwargs = {} )
        创建一个定时器,在经过间隔N秒后,将使用参数args和关键字参数kwargs运行函数。

      cancel()
        停止计时器,取消执行计时器的操作。这仅在定时器仍处于等待阶段时才有效。

    def hello():
        print "hello, world"
    
    t = Timer(30.0, hello)
    t.start()  # 30秒之后print

    九、使用with语句

      此模块提供的具有acquire()和 release()方法的所有对象都可以用作with 语句的上下文管理器。

      在输入块时将调用acquire()方法,并在退出块时调用release()方法。

      目前Lock,RLock,Condition, Semaphore,和BoundedSemaphore 对象都可以用作 with声明上下文管理。

    import threading
    
    some_rlock = threading.RLock()
    
    with some_rlock:
      print "some_rlock is locked while this executes"
  • 相关阅读:
    leetcode_697. 数组的度
    645. 错误的集合
    leetcode_448. 找到所有数组中消失的数字
    leetcode_628. 三个数的最大乘积
    leetcode_414. 第三大的数
    leetcode_495. 提莫攻击
    leetcode_485. 最大连续1的个数
    在 Mac、Linux、Windows 下Go交叉编译
    Goland基本操作
    etcd搭建及基本使用
  • 原文地址:https://www.cnblogs.com/leozhanggg/p/10317494.html
Copyright © 2020-2023  润新知