使用方法:
thread包:有问题,不好用,python3中改成了_thread
使用方法:_thread.start_new_thead(func_name, tuple)
参数两个,一个是需要运行的函数名,第二是函数的参数作为元祖使用,为空则使用空元祖
注意:如果函数只有一个参数,需要参数后由一个逗号
如_thread.start_new_thread(loop1,("wjw", ))
threading包: python3中常用的包
使用方法:t = threading.Thread(target=xxx, args=(xxx,))
t.start():启动多线程
t.join(): 等待多线程执行完成
守护线程-daemon
- 如果在程序中将子线程设置成守护线程,则子线程会在主线程结束的时候自动退出
使用方法:t.setDaemon(True)或者t.daemon = True
线程常用属性:
- threading.currentThread:返回当前线程变量
- threading.enumerate: 返回一个包含正在运行的线程的list,正在运行的线程指的是线程启动后,结束前
- threading.activeCount: 返回正在运行的线程数量,效果跟len(threading.enumerate)相同
- thr.setName: 给线程设置名字
- thr.getName: 获得线程的名字
import time import threading def loop1(): # ctime 得到当前时间 print('Start loop 1 at :', time.ctime()) # 睡眠多长时间,单位是秒 time.sleep(6) print('End loop 1 at:', time.ctime()) def loop2(): # ctime 得到当前时间 print('Start loop 2 at :', time.ctime()) # 睡眠多长时间,单位是秒 time.sleep(1) print('End loop 2 at:', time.ctime()) def loop3(): # ctime 得到当前时间 print('Start loop 3 at :', time.ctime()) # 睡眠多长时间,单位是秒 time.sleep(5) print('End loop 3 at:', time.ctime()) def main(): print("Starting at:", time.ctime()) # 生成threading.Thread实例 t1 = threading.Thread(target=loop1, args=( )) # setName是给每一个子线程设置一个名字 t1.setName("THR_1") t1.start() t2 = threading.Thread(target=loop2, args=( )) t2.setName("THR_2") t2.start() t3 = threading.Thread(target=loop3, args=( )) t3.setName("THR_3") t3.start() # 预期3秒后,thread2已经自动结束, time.sleep(3) # enumerate 得到正在运行子线程,即子线程1和子线程3 for thr in threading.enumerate(): # getName能够得到线程的名字 print("正在运行的线程名字是: {0}".format(thr.getName())) print("正在运行的子线程数量为: {0}".format(threading.activeCount())) print("All done at:", time.ctime()) if __name__ == "__main__": main() # 一定要有while语句 # 因为启动多线程后本程序就作为主线程存在 # 如果主线程执行完毕,则子线程可能也需要终止 while True: time.sleep(10)
继承thread的方法:
- 直接继承Thread
- 必须重写run函数,因为当类实例运行的时候就是在运行run函数
- 类实例可以直接运行
import threading import time # 1. 类需要继承自threading.Thread class MyThread(threading.Thread): def __init__(self, arg): super(MyThread, self).__init__() self.arg = arg # 2 必须重写run函数,run函数代表的是真正执行的功能 def run(self): time.sleep(2) print("The args for this class is {0}".format(self.arg)) for i in range(5): t = MyThread(i) t.start() t.join() print("Main thread is done!!!!!!!!")
semaphore:是一个信号量类,每次有线程获得信号量的时候(即acquire())计数器-1,释放信号量时候(release())计数器+1,计数器为0的时候其它线程就被阻塞无法获得信号量
import time import threading def foo(): time.sleep(2) #程序休息2秒 print("ok",time.ctime()) for i in range(20): t1=threading.Thread(target=foo,args=()) #实例化一个线程 t1.start() #启动线程
上述程序会在很短的时间内生成20个线程来打印一句话,如果在主机执行IO密集型任务的时候再执行这种类型的程序时,计算机就有很大可能会宕机,这时候就可以为这段程序添加一个计数器功能,来限制一个时间点内的线程数量,比如设置一个Semaphore(5),这时每次就只能有5个线程同时运行:
import time import threading s1=threading.Semaphore(5) #添加一个计数器 def foo(): s1.acquire() #计数器获得锁 time.sleep(2) #程序休眠2秒 print("ok",time.ctime()) s1.release() #计数器释放锁 for i in range(20): t1=threading.Thread(target=foo,args=()) #创建线程 t1.start() #启动线程
threading.Timer:利用多线程在指定时间后调用一个函数
import threading import time def func(): print("I am running.........") time.sleep(4) print("I am done......") if __name__ == "__main__": t = threading.Timer(6, func) t.start() i = 0 while True: print("{0}***************".format(i)) time.sleep(3) i += 1
输出结果如下:
0*************** 1*************** I am running......... 2*************** 3*************** I am done...... 4*************** 5***************