zoukankan      html  css  js  c++  java
  • threading模块

    #更高级别的threading不仅提供了Thread类,还提供了各种非常好用的同步机制。
    #_thread模块不支持守护线程,当主线程退出时,所有子线程无论是否在工作,都会被强制退出。threading模块支持守护线程,守护线程一般时一个等待客户请求的服务器,如果没有客户提出请求,就一直等着。如果设定一个线程为守护线程,就表示这个线程不重要,在进程退出时,不用等待这个线程退出。如果主线程退出时不用等待子线程完成,就要设定这些线程的daemon属性,即在线程Thread.start()开始前,调用setDaemon()函数设定线程的daemon标志(Thread.setDaemon(True)),表示这个线程“不重要”,如果一定要等待子线程执行完成再退出主线程,就什么都不用做或显式调用Thread.setDaemon(False)以保证daemon标志为False,可以调用Thread.isDaemon()函数判断daemon标志的值。新的子线程会继承父线程的daemon标志,整个Python在所有非守护线程退出后才会结束,即进程中没有非守护线程存在时才会结束。
     
    threading的thread类
    #Thread有很多_thread模块里没有的函数,Thread对象的函数很丰富。下面创建一个Thread的实例,传给他一个函数。示例如下:
     1 #!/usr/bin/python3
     2 #-*-coding:UTF-8-*-
     3 #threading的thread类
     4 
     5 import threading
     6 from time import sleep
     7 from datetime import datetime
     8 
     9 loops=[4,2]
    10 date_time_format='%y-%M-%d %H:%M:%S'
    11 
    12 def date_time_str(date_time):
    13     return datetime.strftime(date_time,date_time_format)
    14 
    15 def loop(n_loop,n_sec):
    16     print('线程(',n_loop,')开始执行:',date_time_str(datetime.now()),',先休眠(',n_sec,')秒')
    17     sleep(n_sec)
    18     print('线程(',n_loop,')休眠结束,结束于:',date_time_str(datetime.now()))
    19 
    20 def main():
    21     print('---所有线程开始执行:',date_time_str(datetime.now()))
    22     threads=[]
    23     n_loops=range(len(loops))
    24 
    25     for i in n_loops:
    26         t=threading.Thread(target=loop,args=(i,loops[i]))
    27         threads.append(t)
    28 
    29     for i in n_loops:        #start threads
    30         threads[i].start()
    31 
    32     for i in n_loops:        #wait for all
    33         threads[i].join()    #thread to finish
    34 
    35     print('---所有线程执行结束于:',date_time_str(datetime.now()))
    36 
    37 if __name__=='__main__':
    38     main()
    #执行结果如下:
    1 D:Pythonworkspace>python threading_thread.py
    2 ---所有线程开始执行: 18-31-30 09:31:54
    3 线程( 0 )开始执行: 18-31-30 09:31:54 ,先休眠( 4 )秒
    4 线程( 1 )开始执行: 18-31-30 09:31:54 ,先休眠( 2 )秒
    5 线程( 1 )休眠结束,结束于: 18-31-30 09:31:56
    6 线程( 0 )休眠结束,结束于: 18-31-30 09:31:58
    7 ---所有线程执行结束于: 18-31-30 09:31:58
    #由执行结果我们看到,实例化一个Thread(调用Thread())与调用_thread.start_new_thread()最大的区别是新的线程不会立即开始。创建线程对象却不想马上开始运行线程时,Thread是一个很有用的同步特性。所有线程都创建之后,再一起调用start()函数启动,而不是每创建一个线程就启动。而且不用管理一堆锁的状态(分配锁、获得锁、释放锁、检查锁的等状态),只要简单对每个线程调用join()主线程,等待子线程结束即可。join()还可以设置timeout参数,即主线程的超时时间。
    #join()的另一个比较重要的方面是可以完全不用调用。一旦线程启动,就会一直运行,直到线程的函数结束并退出为止。如果主线程除了等线程结束外,还有其他事情要做,就不用调用join(),只有在等待线程结束时才调用。
    #我们再看示例,创建一个Thread的实例,并传给它一个可调用的类对象。代码如下:
     1 #!/usr/bin/python3
     2 #-*-coding:UTF-8-*-
     3 #threading_join()
     4 
     5 import threading
     6 from time import sleep
     7 from datetime import datetime
     8 
     9 loops=[4,2]
    10 date_time_format='%y-%M-%d %H:%M:%S'
    11 
    12 class ThreadFunc(object):
    13     def __init__(self,func,args,name=''):
    14         self.name=name
    15         self.func=func
    16         self.args=args
    17 
    18     def __call__(self):
    19         self.func(*self.args)
    20 
    21 def date_time_str(date_time):
    22     return datetime.strftime(date_time,date_time_format)
    23 
    24 def loop(n_loop,n_sec):
    25     print('线程(',n_loop,')开始执行:',date_time_str(datetime.now()),',先休眠(',n_sec,')秒')
    26     sleep(n_sec)
    27     print('线程(',n_loop,')休眠结束,结束于:',date_time_str(datetime.now()))
    28 
    29 def main():
    30     print('---所有线程开始执行:',date_time_str(datetime.now()))
    31     threads=[]
    32     nloops=range(len(loops))
    33 
    34     for i in nloops:
    35         t=threading.Thread(target=ThreadFunc(loop,(i,loops[i]),loop.__name__))
    36         threads.append(t)
    37 
    38     for i in nloops:     #start all threads
    39         threads[i].start()
    40 
    41     for i in nloops:    #wait for completion
    42         threads[i].join()
    43 
    44     print('---所有线程执行结束于:',date_time_str(datetime.now()))
    45 
    46 if __name__=='__main__':
    47     main()
    #执行结果如下:
    1 D:Pythonworkspace>python threading_join().py
    2 ---所有线程开始执行: 18-30-30 11:30:26
    3 线程( 0 )开始执行: 18-30-30 11:30:26 ,先休眠( 4 )秒
    4 线程( 1 )开始执行: 18-30-30 11:30:26 ,先休眠( 2 )秒
    5 线程( 1 )休眠结束,结束于: 18-30-30 11:30:28
    6 线程( 0 )休眠结束,结束于: 18-30-30 11:30:30
    7 ---所有线程执行结束于: 18-30-30 11:30:30
    #由执行结果看到,与传一个函数很相似的一个方法是,在创建线程时,传一个可调用的类的实例供线程启动时执行,这是多线程编程的一个面向对象的方法。相对于一个或多个函数来说,类对象可以使用类的强大功能。创建线程时,Thread对象会调用ThreadFunc对象,这时会用到一个特殊函数__call__()。由于已经有了要用的参数,因此不用再传到Thread()的构造函数中。对于一个参数的元组,要使用self.func(*self.args)方法。
    #从Thread派生一个子类,创建这个子类的实例,从上面的代码派生的代码如下:
     1 #!/usr/bin/python3
     2 #-*-coding:UTF-8-*-
     3 #threading___call__
     4 
     5 import threading
     6 from time import sleep
     7 from datetime import datetime
     8 
     9 loops=[4,2]
    10 date_time_format='%y-%M-%d %H:%M:%S'
    11 
    12 class MyThread(threading.Thread):
    13     def __init__(self,func,args,name=''):
    14         threading.Thread.__init__(self)
    15         self.name=name
    16         self.func=func
    17         self.args=args
    18 
    19     def getResult(self):
    20         return self.res
    21 
    22     def run(self):
    23         print('starting',self.name,'at:',date_time_str(datetime.now()))
    24         self.res=self.func(*self.args)
    25         print(self.name,'finished at:',date_time_str(datetime.now()))
    26 
    27 def date_time_str(date_time):
    28     return datetime.strftime(date_time,date_time_format)
    29 
    30 def loop(n_loop,n_sec):
    31     print('线程(',n_loop,')开始执行:',date_time_str(datetime.now()),',先休眠(',n_sec,')秒')
    32     sleep(n_sec)
    33     print('线程(',n_loop,')休眠结束,结束于:',date_time_str(datetime.now()))
    34 
    35 def main():
    36     print('---所有线程开始执行:',date_time_str(datetime.now()))
    37     threads=[]
    38     n_loops=range(len(loops))
    39 
    40     for i in n_loops:
    41         t=MyThread(loop,(i,loops[i]),loop.__name__)
    42         threads.append(t)
    43 
    44     for i in n_loops:
    45         threads[i].start()
    46 
    47     for i in n_loops:
    48         threads[i].join()
    49 
    50     print('---所有线程执行结束于:',date_time_str(datetime.now()))
    51 
    52 if __name__=='__main__':
    53     main()
    #执行结果如下:
     1 D:Pythonworkspace>python threading_call.py
     2 ---所有线程开始执行: 18-12-30 15:12:55
     3 starting loop at: 18-12-30 15:12:55
     4 线程( 0 )开始执行: 18-12-30 15:12:55 ,先休眠( 4 )秒
     5 starting loop at: 18-12-30 15:12:55
     6 线程( 1 )开始执行: 18-12-30 15:12:55 ,先休眠( 2 )秒
     7 线程( 1 )休眠结束,结束于: 18-12-30 15:12:57
     8 loop finished at: 18-12-30 15:12:57
     9 线程( 0 )休眠结束,结束于: 18-12-30 15:12:59
    10 loop finished at: 18-12-30 15:12:59
    11 ---所有线程执行结束于: 18-12-30 15:12:59
    #由代码片段和执行结果我们看到,子类化Thread,MyThread子类的构造函数一定要先调用基类的构造函数,特殊函数__call__()在子类中,名字要改为run()。在Thread类中,加入一些用于调试的输出信息,把代码保存到MyThread模块中,并导入这个类。使用self.func()函数运行这些函数,并把结果保存到实现的self.res属性中,创建一个新函数getResult()得到结果。
  • 相关阅读:
    EF Power Tools
    ntsysv命令
    chpasswd 批量更新用户口令
    at定时执行任务命令详解
    shell
    为什么使用 shell 编程
    shell
    redis cluster 3.0
    CSS命名规则规范整理
    log4j:WARN No appenders could be found for logger
  • 原文地址:https://www.cnblogs.com/DLHe/p/8411242.html
Copyright © 2011-2022 走看看