多线程_2链接:https://blog.csdn.net/weixin_42394170/article/details/95875764
多线程 vs 多进程
-
程序:一堆代码以文本形式存入一个文档
-
进程: 程序运行的一个状态
- 包含地址空间,内存,数据栈等
- 每个进程由自己完全独立的运行环境,多进程共享数据是一个问题
-
线程
- 一个进程的独立运行片段,一个进程可以由多个线程
- 轻量化的进程
- 一个进程的多个现成间共享数据和上下文运行环境
- 共享互斥问题
-
全局解释器锁(GIL)
- Python代码的执行是由python虚拟机进行控制
- 在主循环中稚嫩更有一个控制线程在执行
-
Python包
- thread:有问题,不好用,python3改成了_thread
- threading: 通行的包
- 案例01: 顺序执行,耗时比较长
- 案例02: 改用多线程,缩短总时间,使用_thread
- 案例03: 多线程,传参数
-
threading的使用
- 直接利用threading.Thread生成Thread实例
- t = threading.Thread(target=xxx, args=(xxx,))
- t.start():启动多线程
- t.join(): 等待多线程执行完成
- 案例04
- 案例05: 加入join后比较跟案例04的结果的异同
- 守护线程-daemon
- 如果在程序中将子线程设置成守护现成,则子线程会在主线程结束的时候自动退出
- 一般认为,守护线程不中要或者不允许离开主线程独立运行
- 守护线程案例能否有效果跟环境相关
- 案例06非守护线程
- 案例07守护线程
- 线程常用属性
- threading.currentThread:返回当前线程变量
- threading.enumerate:返回一个包含正在运行的线程的list,正在运行的线程指的是线程启动后,结束前的状态
- threading.activeCount: 返回正在运行的线程数量,效果跟 len(threading.enumerate)相同
- thr.setName: 给线程设置名字
- thr.getName: 得到线程的名字
- 直接继承自threading.Thread
- 直接继承Thread
- 重写run函数
- 类实例可以直接运行
- 案例09
- 案例10, 工业风案例
- 直接利用threading.Thread生成Thread实例
**案例01**
'''
利用time函数,生成两个函数
顺序调用
计算总的运行时间
'''
import time
def loop1():
print("Loop1 start at:", time.ctime())
time.sleep(2)
print("Loop1 end at:", time.ctime())
def loop2():
print("Loop2 start at:", time.ctime())
time.sleep(4)
print("Loop2 end at:", time.ctime())
def main():
print("Main start at:", time.ctime())
loop1()
loop2()
print("Main end at:", time.ctime())
if __name__ == '__main__':
main()
# 结果:
# Main start at: Sat Jul 13 11:48:12 2019
# Loop1 start at: Sat Jul 13 11:48:12 2019
# Loop1 end at: Sat Jul 13 11:48:14 2019
# Loop2 start at: Sat Jul 13 11:48:14 2019
# Loop2 end at: Sat Jul 13 11:48:18 2019
# Main end at: Sat Jul 13 11:48:18 2019
**案例02**
'''
利用time函数,生成两个函数
顺序调用
计算总的运行时间
'''
import time
import _thread as thread
def loop1():
print("Loop1 start at:",time.ctime())
time.sleep(2)
print("Loop1 end at:",time.ctime())
def loop2():
print("Loop2 start at:",time.ctime())
time.sleep(4)
print("Loop2 end at:",time.ctime())
def main():
print("Main start at:",time.ctime())
# 启动多线程的意思是用多线程去执行某个函数
# 启动多线程函数为start_new_thead
# 参数两个,一个是需要运行的函数名,第二是函数的参数作为元祖使用,为空则使用空元祖
# 注意:如果函数只有一个参数,需要参数后有一个逗号——》因为这是元组
thread.start_new_thread(loop1,())#如果loop有参数,则再() 内给出
thread.start_new_thread(loop2,())
print("Main end at:",time.ctime())
if __name__ == '__main__':
main()
#结果:
# Main start at: Sat Jul 13 11:57:50 2019
# Main end at: Sat Jul 13 11:57:50 2019
#因为主程序不会等线程执行完,它是直接print下来
import time
import _thread as thread
def loop1():
print("Loop1 start at:",time.ctime())
time.sleep(2)
print("Loop1 end at:",time.ctime())
def loop2():
print("Loop2 start at:",time.ctime())
time.sleep(4)
print("Loop2 end at:",time.ctime())
def main():
print("Main start at:",time.ctime())
# 启动多线程的意思是用多线程去执行某个函数
# 启动多线程函数为start_new_thead
# 参数两个,一个是需要运行的函数名,第二是函数的参数作为元祖使用,为空则使用空元祖
# 注意:如果函数只有一个参数,需要参数后有一个逗号——》因为这是元组
thread.start_new_thread(loop1,())#如果loop有参数,则再() 内给出
thread.start_new_thread(loop2,())
print("Main end at:",time.ctime())
if __name__ == '__main__':
main()
while True:
time.sleep(1)#不让主程序执行完,会等待线程
# 结果
# # Main start at: Sat Jul 13 12:01:35 2019
# # Main end at: Sat Jul 13 12:01:35 2019
# # Loop1 start at: Sat Jul 13 12:01:35 2019
# # Loop2 start at: Sat Jul 13 12:01:35 2019
# # Loop1 end at: Sat Jul 13 12:01:37 2019
# # Loop2 end at: Sat Jul 13 12:01:39 2019
**案例03**
import time
import _thread as thread
def loop1(int1):
print("Loop1 start at:",time.ctime())
print("我是参数", int1)
time.sleep(2)
print("Loop1 end at:",time.ctime())
def loop2(int1,int2):
print("Loop2 start at:",time.ctime())
print("我是参数",int1,"和参数",int2)
time.sleep(4)
print("Loop2 end at:",time.ctime())
def main():
print("Main start at:",time.ctime())
thread.start_new_thread(loop1,("weiwei",))#如果loop有参数,则再() 内给出
thread.start_new_thread(loop2,("xixi","haha"))
print("Main end at:",time.ctime())
if __name__ == '__main__':
main()
while True:
time.sleep(1)
**案例04**
import time
import threading
def loop1(int1):
print("Loop1 start at:",time.ctime())
print("我是参数", int1)
time.sleep(2)
print("Loop1 end at:",time.ctime())
def loop2(int1,int2):
print("Loop2 start at:",time.ctime())
print("我是参数",int1,"和参数",int2)
time.sleep(4)
print("Loop2 end at:",time.ctime())
def main():
print("Main start at:",time.ctime())
t1 = threading.Thread(target=loop1,args=("asd",))
t1.start()
t2 = threading.Thread(target = loop2,args = ("haha","xixi"))
t2.start()
print("Main end at:",time.ctime())
if __name__ == '__main__':
main()
while True:
time.sleep(10)
**案例05**
import time
import threading
def loop1(int1):
print("Loop1 start at:",time.ctime())
print("我是参数", int1)
time.sleep(2)
print("Loop1 end at:",time.ctime())
def loop2(int1,int2):
print("Loop2 start at:",time.ctime())
print("我是参数",int1,"和参数",int2)
time.sleep(4)
print("Loop2 end at:",time.ctime())
def main():
print("Main start at:",time.ctime())
t1 = threading.Thread(target=loop1,args=("asd",))
t1.start()
t2 = threading.Thread(target = loop2,args = ("haha","xixi"))
t2.start()
t1.join()
t2.join()
print("Main end at:",time.ctime())
if __name__ == '__main__':
main()
while True:
time.sleep(1)
# 结果
# Main start at: Sat Jul 13 12:42:07 2019
# Loop1 start at: Sat Jul 13 12:42:07 2019
# 我是参数 asd
# Loop2 start at: Sat Jul 13 12:42:07 2019
# 我是参数 haha 和参数 xixi
# Loop1 end at: Sat Jul 13 12:42:09 2019
# Loop2 end at: Sat Jul 13 12:42:11 2019
# Main end at: Sat Jul 13 12:42:11 2019
**案例06**
import time
import threading
def fun():
print("fun start")
time.sleep(2)
print("end fun")
print("Main start")
t1 = threading.Thread(target = fun,args = ())
t1.start()
time.sleep(1)
print("Main end")
**案例07**
import time
import threading
def fun():
print("fun start")
time.sleep(2)
print("end fun")
print("Main start")
t1 = threading.Thread(target = fun,args = ())
#要在start前设置
t1.setDaemon(True)#或者下面的话
#t1.daemon = True
t1.start()
time.sleep(1)
print("Main end")
**案例08**
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)
**案例09**
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函数代表的是真正执行的功能,start函数调用的就是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!!!!!!!!")
**案例10**
import threading
from time import sleep, ctime
loop = [4,2]
class ThreadFunc:
def __init__(self, name):
self.name = name
def loop(self, nloop, nsec):
'''
:param nloop: loop函数的名称
:param nsec: 系统休眠时间
:return:
'''
print('Start loop ', nloop, 'at ', ctime())
sleep(nsec)
print('Done loop ', nloop, ' at ', ctime())
def main():
print("Starting at: ", ctime())
# ThreadFunc("loop").loop 跟一下两个式子相等:
# t = ThreadFunc("loop")
# t.loop
# 以下t1 和 t2的定义方式相等
t = ThreadFunc("loop")
t1 = threading.Thread( target = t.loop, args=("LOOP1", 4))
# 下面这种写法更西方人,工业化一点
t2 = threading.Thread( target = ThreadFunc('loop').loop, args=("LOOP2", 2))
# 常见错误写法
#t1 = threading.Thread(target=ThreadFunc('loop').loop(100,4))
#t2 = threading.Thread(target=ThreadFunc('loop').loop(100,2))
t1.start()
t2.start()
t1.join( )
t2.join()
print("ALL done at: ", ctime())
if __name__ == '__main__':
main()