Python—多线程编程(一)线程的创建,管理,停止
先简单介绍一下线程的概念(以下内容来源于百度):
线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。
说白了就是线程就是完成某个特定功能的一段代码,但线程的开销要比进程小的多。一个Python程序至少有一个线程,那就是Python的主线程,程序启动后由Python解释器负责创建主线程,程序结束时由Python解释器来负责结束主线程。
接下来就进如主题,Python的多线程编程。
Python中由两个模块可以用来多线程编程,_thread 和 threading。前者提供了多线程编程的低级API,后者提供了更高级的API,使用起来也更加便捷,其时基于_thread的封装,接下来就用thread模块来实现多线程的编写。
1.简单介绍threading模块的三种常用函数:
#Threading模块
threading.active_count() 返回当前处于活动状态的线程个数
threading.current_thread() 返回当前的Thread对象
threading.main_thread() 返回主线程对象,主线程是Python解释器启动的线程
上代码试试感觉:
#当前线程
t = threading.current_thread()
#当前线程的名字
print(t.name)
#当前处于活动状态的线程的个数
print(threading.active_count())
#主线程
t = threading.main_thread()
#主线程的名字
print(t.name)
后台结果:
结果看出,目前的线程为Python的主线程,名字为MainThread
2.创建线程
创建一个可执行的线程需要 线程对象 和 线程体
线程对象:threading模块线程类Thread所创建的对象
线程体:线程的执行函数,线程启动会执行该函数,线程所处理的代码是在线程体中编写的
创建线程体的两种主要的方法:
(1)自定义函数体为线程体
(2)继承Thread类重写run()方法,run()方法作为线程
创建线程对象:
threading.Thread(target = None,name = None,args = ())
target 是线程体,即自定义函数 name 设置线程名,若没有设置则Python解释器会为其自动分配一个名字 args 为自定义函数提供参数,是一个元组类型
自定义函数为线程体(自我感觉这个用起来更方便):
#自定义线程函数
#线程方法
def threading_body():
#当前对象线程
t = threading.current_thread()
for i in range(1,6):
#当前线程名
print("第{0}次执行线程 {1}".format(i,t.name))
#线程休眠
time.sleep(1)
print("线程{0}执行完成".format(t.name))
def main():
#创建线程t1对象
t1 = threading.Thread(target = threading_body,name = '线程1')
#启动线程1
t1.start()
# 创建线程t2对象
t2 = threading.Thread(target = threading_body,name = '线程2')
#启动线程2
t2.start()
if __name__ == '__main__':
main()
后台执行结果:
若没有进行线程休眠,执行结果如下:
由此可见线程休眠是多么的重要,线程的执行时交替执行的并没有一定的执行顺序
继承重写run()方法:
class MyThread(threading.Thread):
def __init__(self,name = None):
super().__init__(name = name)
def run(self):
#当前线程对象
t = threading.current_thread()
for i in range(1,6):
print("第{0}次执行线程{1}".format(i,t.name))
time.sleep(1)
print("{0}执行完成".format(t.name))
def main():
#创建线程对象1
t1 = MyThread()
#启动线程1
t1.start()
#创建线程2
t2 = MyThread()
#启动线程2
t2.start()
if __name__ == '__main__':
main()
后台执行结果:
我在这里并没有设置线程的名字,而是由解释器自动给其分配的名字。
3.线程管理
#线程管理
'''
等待线程结束
当前线程调用t1线程的join()方法时则阻塞当前线程,等待t1线程的结束,如果t1线程结束或等待超时,则当前线程回到活动状态继续执行
value = 0
def thread_body():
global value
print("线程1开始执行...")
for i in range(3):
print("线程1正在执行")
value += 1
time.sleep(1)
print("线程1结束...")
def main():
t1 = threading.Thread(target = thread_body,name = '线程1')
t1.start()
print("当前线程名字: ".format(threading.current_thread().name))
#当前线程调用t1线程的join方法,阻塞当前线程,等待t1线程结束或等待超时
t1.join()
print('value = {0}'.format(value))
print("主线程结束")
if __name__ == '__main__':
main()
后台执行结果:
怎么证明主线程让阻塞了呢,可以将t1.join()这行代码注释掉,执行结果如下:
这样两张图进行对比,那么就很容易的看出主线程确实让阻塞了
4.线程停止
#线程停止(手动将线程停止)
isrunning = True
def threading_body():
while isrunning:
print("线程1正在执行")
time.sleep(6)
print("已退出执行")
def main():
t1 = threading.Thread(target = threading_body,name = '线程1')
t1.start()
command = input('输入停止命令:')
if command == 'exit':
global isrunning
isrunning = False
if __name__ == '__main__':
main()
后台执行结果:
这是我在一本书上学到的内容,和大家一起分享,要是觉得有用的话能不能点个赞呀
未完待续!