文章目录
必备概念
什么是线程?
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
线程与进程之间的关系?
进程包含线程,进程最少包含一个线程。
创建线程
概念理解完毕,那就开始创建线程把,首先使用自定义函数创建
(1)自定义函数创建线程
任务目标:让程序员一边听歌一边打代码
import time
from threading import Thread
def listen_to_music(times):
for i in range(times):
print("听音乐")
time.sleep(1)
def call_code(times):
for i in range(times):
print("打代码")
time.sleep(1)
def main():
thread_one=Thread(target=listen_to_music,args=(3,))
thread_two=Thread(target=call_code,args=(3,))
thread_one.start()
thread_two.start()
if __name__ == '__main__':
main()
'''
运行结果:
唱歌
打代码
唱歌
打代码
唱歌
打代码
'''
(2)使用类创建线程
本质:通过继承Tread类并重写Thread中的run方法,来创建线程。为了跟(1)中的结果一致,我重写了两次。代码如下:
import time
from threading import Thread
class Programmer_routine_music(Thread):
def __init__(self,times):
super().__init__()
self.times=times
def run(self):
for i in range(self.times):
print("听歌")
time.sleep(1)
class Programmer_routine_code(Thread):
def __init__(self,times):
super().__init__()
self.times=times
def run(self):
for i in range(self.times):
print("打代码")
time.sleep(1)
def main():
Programmer_routine_music(3).start()
Programmer_routine_code(3).start()
if __name__ == '__main__':
main()
'''
运行结果:
唱歌
打代码
唱歌
打代码
唱歌
打代码
'''
**结论:这两种都是创建线程的方法,值得肯定的是,第一种方法相对简单些。**
join()方法
join()方法的作用?
join()方法:当前线程执行完毕才会执行其他线程
代码示例:
import time
from threading import Thread
def listen_to_music(times):
for i in range(times):
print("听音乐")
time.sleep(1)
def call_code(times):
for i in range(times):
print("打代码")
time.sleep(1)
def main():
thread_one=Thread(target=listen_to_music,args=(3,))
thread_two=Thread(target=call_code,args=(3,))
thread_one.start()
thread_one.join()
thread_two.start()
if __name__ == '__main__':
main()
'''
听音乐
听音乐
听音乐
打代码
打代码
打代码
'''
结论:加入join()再某些场景是很有必要的,例如在爬虫的时候,子线程是获取了数据才能交给主线程处理,这时候就能用到join()方法,对其他线程形成堵塞,避免程序报错。很显然在本案例代码中并不适用。
守护进程
什么是守护?
当主线程存活的时候,守护线程才会存活,当主线程结束后,守护线程会自动杀死自己,结束运行。
如何形象的理解?
运行qq。并打开了多个聊天窗口。这个运行的qq就可以理解为主线程,多个聊天窗口就可以理解为子线程。当把qq关闭,多个聊天窗口也会自动关闭。
代码示例:
(1)无守护线程案例
import time
from threading import Thread
def listen_to_music(times):
for i in range(times):
print("听音乐")
time.sleep(1)
def call_code(times):
for i in range(times):
print("打代码")
time.sleep(1)
def main():
thread_one=Thread(target=listen_to_music,args=(3,))
thread_two=Thread(target=call_code,args=(3,))
thread_one.start()
thread_two.start()
print("主线程结束")
if __name__ == '__main__':
main()
'''
运行结果:
听音乐
打代码
主线程结束
打代码
听音乐
打代码
听音乐
'''
这里不得不的不说的小白误点!
你可能认为如果没有设置守护线程,当子线程在执行的时候,主线程会进行等待!,这当然不会,主线程会自动执行下去。那么如何让主线程等待子线程呢?这个答案就是上面所说的join()函数,让当前函数执行完毕,才会执行其他函数。
(2)有守护线程案例
import time
from threading import Thread
def listen_to_music(times):
for i in range(times):
print("听音乐")
time.sleep(1)
def call_code(times):
for i in range(times):
print("打代码")
time.sleep(1)
def main():
thread_one=Thread(target=listen_to_music,args=(3,))
thread_two=Thread(target=call_code,args=(3,))
thread_one.setDaemon(True)
thread_two.setDaemon(True)
thread_one.start()
thread_two.start()
print("主线程结束")
if __name__ == '__main__':
main()
'''
运行结果:
听音乐
打代码
主线程结束
'''
结论:在案例二子线程并没有执行完毕,整个程序就执行完毕了。可见,守护线程可以让子线程随着主线程的结束而结束。
线程类的一些实例方法
方法名 | 描述 |
---|---|
getName() | 获取线程的名称 |
setName() | 设置线程的名称 |
isAlive() | 判断当前线程存活状态 |
代码示例:
import time
from threading import Thread
def listen_to_music(times):
for i in range(times):
print("听音乐")
time.sleep(1)
def call_code(times):
for i in range(times):
print("打代码")
time.sleep(1)
def main():
thread_one=Thread(target=listen_to_music,args=(3,))
thread_two=Thread(target=call_code,args=(3,))
thread_one.setName("我是子线程一号")
thread_two.setName("我是子线程二号")
thread_one.start()
print(thread_one.getName())
print(thread_two.getName())
thread_two.start()
print(thread_one.isAlive())
print(thread_two.isAlive())
if __name__ == '__main__':
main()
'''
听音乐
我是子线程一号
我是子线程二号
打代码True
True
打代码
听音乐
打代码听音乐
'''
线程之间共享全局变量
代码示例:
任务目标,让num通过两个子线程累加3次
import threading
num=100
def thread1(times):
global num
for i in range(times):
num+=1
print(num)
def thread2(times):
global num
for i in range(times):
num+=1
print(num)
def main():
t1=threading.Thread(target=thread1,args=(3,))
t2=threading.Thread(target=thread2,args=(3,))
t1.start()
t2.start()
if __name__ == '__main__':
main()
'''
运行结果:
101
102
103
104
105
106
'''
总结:使用global将num设置为全局变量即可多个线程共享
来一波,推送吧!
群号:781121386
群名:人生苦短,我学编程
欢迎大家加入我们,一起交流技术!!!