1.签名
def
init(self,group=None,target=None,name=None,agrs=(),kwargs=None,*,daemon=None)
group :值为None,为将来扩展保留
target:线程调用的对象,就是目标函数
name:为线程起个名字
args:为目标函数传递实参,元组类型封装
kwargs:为目标函数关键字传参,字典类型封装
2.线程启动
def
abc():
print(‘this is a function’)
t=threading.Thread(target=abc,name=’abc’)
t.start()
通过threading.Thread创建一个线程对象,target是目标函数,name可以指定名称。
线程启动需要调用start方法。
线程之所以执行函数,是因为线程中就是执行代码的,而最简单的封装就是函数,所以还是函数调用。
函数执行完,线程就退出了。
3.线程退出
python中没有退出线程的方法,线程在一下情况退出.
1.线程函数内语句执行完毕
2.线程内抛出异常
另外python线程没有优先级,没有线程组的概念。不能被销毁,停止,挂起,和恢复,中断。
4.线程传参
位置参数使用元组封装,threading.Thread参数开启agrs选项,如args=(1,2,3,)
关键字参数使用字典封装,threading.Thread参数开启kwagrs选项,如kwargs={‘a’:1,’b’:2}
5.threading的属性和方法
current_thread():返回当前线程对象
main_thread():返回主线程对象
active_count():放回活着的线程总数
enumerate():返回当前所有活着的线程
get_ident():返回当前线程ID,非0整数
6.Thread实例的属性和方法
name:只是一个名字,可以重名。getName(),setName()获取,设置这个名词。
ident:线程ID,非0整数。线程启动后才有ID,否则为None。线程退出,此id依旧可以访问。ID 可以重复使用。
is_alive();判断线程是否存活
start():启动线程,每一个线程必须且只能执行该方法一次。
run():启动线程函数。
使用run方法不能开启新的线程,只是在主线程进行普通函数调用。
7.多线程
顾名思义,多个线程。一个进程中如果有多个线程,就是多线程,实现一种并发。
一个进程中至少有一个线程,并且作为程序的入口,这个线程就是主线程。一个进程至少有一个主线程。其他线程称为工作线程。
8.线程安全
如一下代码打印结果所示(仅ipython可演示),多个线程同时打印字符串‘this is
xxx’时打印格式错乱,有的两行合成一行,有的一行下面有多个空行。原因是print函数除了打印完字符串外还会打印换行符。当线程A打印完字符串准备打印换行时(字符串和换行符分步打印),发生了线程切换,线程B打印字符串。经过数次调度后又切回线程A,这时再打印换行符,但是格式已经错乱。这说明print函数是线程不安全的。
解决上面问题可以改造print(’this is
{}\n‘.forma(i),end=”),讲字符串和换行符格式化为一个新的字符串。由于字符串的原子性,可以保证正常打印。
9.daemon线程和non-daemon线程
注:Python中daemon与Linux中的daemon没有关系
进程靠线程执行代码,至少有一个主线程,其他线程是工作线程。
主线程是第一个启动的线程
父线程:如果线程A启动线程B,A就是B的父线程,B是A的子线程。
在构造线程的时候,可以在Thread类设置daemon属性。
线程daemon属性,默认为False即non-daemon。主线程一定是non-daemon。
线程具有一个daemon属性,可以显示设置为True或False,也可以不设置,则取默认值None。
如果不设置daemon,就取当前线程的daemon来设置(继承至父线程)。
python程序在没有或者的non-daemon线程运行时退出,也就是剩下的只能是daemon线程,主线程才退出,否则主线程只能等待。
子线程daemon
子线程non-daemon
10.join方法
使join方法后,不管是不是daemon,子线程执行完了父线程才退出。
join(timeout=None)是线程的标准方法之一。
一个线程调用另一个线程的join方法,调用者将被堵塞,知道调用线程终止。
一个线程可以被join多次。
timeout参数指定调用者等待多久,没有设置超时将会一直等待直到被调用线程终止。
如果线程A调用线程B,线程B调用线程C,并且线程B join
线程C。那么直到线程C执行完成线程B才会退出。若线程B和线程C都为daemon,那么线程A将会正常退出并终止线程B,C。无论线程B是否join线程C,并不会等待线程B和线程C。
简单说就是调用谁的join方法,就是join谁,就要等谁。
11.daemon应用场景
1.后台任务:如发送心跳包,监控。
2,主线程工作才有用的线程。如主线程维护公共资源,主线程已经清理了,准备退出,而工作线程也将一起退出。
3.随时可被终止的线程
12.定时器Timer/延时执行
threading.Timer继承自Thread,这个类用来定义多久执行一个函数。
Timer(interval,function,args=None,kwargs=None)
start 方法执行之后,Timer对象会处于等待状态,等待interval之后,开始执行function函数。
如果在等待阶段使用cancel方法,就会取消执行。
当然如果函数已经开始执行,再cancel将没有任何效果。

本文详细介绍了Python中多线程的基础知识,包括线程的创建、启动、传参及线程安全等问题。深入探讨了线程的daemon属性、join方法的应用场景及定时器Timer的使用。
1814

被折叠的 条评论
为什么被折叠?



