threading模块介绍以及常用方法
-
介绍
threading模块是Python支持多线程编程的重要模块,该模块是在底层模块_thread的基础上开发的更高层次的线程编程接口,提供了大量的方法和类来支持多线程编程。 -
threading模块常用方法表
方法 | 功能说明 |
---|---|
threading.active_count() | 获取当前处于alive状态的Thread对象数量 |
threading.current_thread() | 获取当前的Thread对象 |
threading.get_ident() | 获取当前线程的线程标识符 |
threading.enumerate() | 获取当前处于alive状态的所有Thread对象列表 |
threading.main_thread() | 获取主线程对象,即启动Python解析器的线程对象 |
threading.stack_size([size]) | 获取创建线程时所使用的栈的大小,如果指定size参数,则用来指定后续创建线程使用的栈大小,size必须是0或大于32K的正整数 |
- 简单例子
# 例 1-1
import threading
'''
0
'''
print(threading.stack_size())
'''
Traceback (most recent call last):
** IDLE Internal Exception:
File "E:\AppData\Python36-32\lib\idlelib\run.py", line 474, in runcode
exec(code, self.locals)
File "C:/Users/Administrator/Desktop/tthreading.py", line 5, in <module>
print(threading.stack_size(32))
ValueError: size not valid: 32 bytes
'''
print(threading.stack_size())
'''
2,因为当前IDLE环境下已经有一个socket线程在运运行着,然后本身作为主线程也正在运行,所以当前活动的线程数为2
'''
print(threading.active_count())
'''
<_MainThread(MainThread, started 7704)>
'''
print(threading.current_thread())
'''
[<_MainThread(MainThread, started 3212)>, <Thread(SockThread, started daemon 10176)>]
'''
print(threading.enumerate())
Thread对象
-
介绍
Thread类支持使用两种方法来创建线程:一种是为构造函数传递一个可调用对象;另一种方法是继承Thread类并在派生类中重写构造方法和run()方法。创建线程对象以后,可以调用其start()方法来启动,该方法自动调用该类对象的run()方法,此时该线程处于alive状态,直至线程的run()方法运行结束。 -
Thread对象成员
成员 | 说明 |
---|---|
start() | 自动调用run()方法,启动线程,执行线程代码 |
run() | 线程代码,用来实现线程的功能与逻辑业务,可在子类中重写该方法来自定义线程的行为 |
__init__(self, group=None,target=None,name=None,args=(),kwargs=None,verbose=None) | 构造函数 |
name | 用来读取或设置线程的名字 |
ident() | 线程标识,非0数字或None(线程未被启动) |
is_alive() | 测试线程是否处于alive状态 |
isAlive() | 测试线程是否处于alive状态 |
daemon | 表示线程是否是守护线程 |
join(timeout=None) | 等待线程结束或超时返回 |
- 简单例子
'''
(1)join([timeout]):阻塞当前线程,等待被调线程结束或超时后再继续执行当前线程的后续代码,参数timeout用来指定最长
等待时间,单位为秒。
(2)isAlive():测试线程是否处于运行状态。
(3)daemon属性:在脚本运行过程中有一个主线程,若在主线程中创建了子线程,当主线程结束时根据子线程daemon属性值得不
同可能会发生下面的两种情况之一:①当某子线程的daemon属性为False时,主线程结束时会检测该子线程是否结束,如果该子线
程尚未完成,则主线程等待它完成后再退出;②当某子线程的daemon属性为True时,主线程运行结束时不对该子线程进行检查而
直接退出,同时所有daemon属性值为True的子线程将随着主线程一起结束,而不论是否运行完成。daemon属性的值默认为False,
如果需要修改,则必须在调用start()方法启动线程之前修改。该讨论不适用于IDLE环境中的交互模式或脚本运行模式,因为在
该环境中的主线程只有在退出IDLE时才终止。
'''
# 例 2-1
# 程序首先输出[15,19]这5个数字,然后程序暂停,几秒钟以后又继续输出[5,9]这5个整数。
import threading
import time
def func(x, y):
for i in range(x, y):
print(i, end='')
time.sleep(10)
t = threading.Thread(target=func, args = (15, 20))
t.start()
t.join(5)
t1 = threading.Thread(target = func, args = (5, 10))
t1.start()
# 例 2-2
import threading
import time
def func(x, y):
for i in range(x, y):
print(i)
t1 = threading.Thread(target=func, args = (15, 20))
t1.start()
t2 = threading.Thread(target = func, args = (5, 10))
t2.start()
# True
print('t1:', t1.isAlive())
# True
print('t2:', t2.isAlive())
# 例 2-3
# 结果输出为:
# False
# True
# 1
import threading
import time
class mythread(threading.Thread):
def __init__(self, num, tname):
threading.Thread.__init__(self, name=tname)
self.num = num
def run(self):
time.sleep(self.num)
print(self.num)
t1 = mythread(1, 't1')
t2 = mythread(5, 't2')
t2.daemon = True
print(t1.daemon)
print(t2.daemon)
t1.start()
t2.start()
线程同步
-
介绍
多线程是为了充分利用硬件资源尤其是CPU资源来提高任务处理速度和效率的技术。将任务拆分成互相协作的多个线程同时运行,那么属于同一个任务的多个线程之间必然会有交互和同步以便互相协作地完成任务。 -
Lock/RLock对象介绍
Lock是比较低级的同步原语,当被锁定以后不属于特定的线程。一个锁有两种状态:locked和unlocked。如果锁处于unlocked状态,acquire()方法将其修改为locked并立即返回;如果锁已经处于locked状态,则阻塞当前线程等待其他线程释放锁,然后将其修改为locked并立即返回。release()方法用来将锁状态由locked修改为unlocked并立即返回,如果锁状态本来已经是unlocked,调用该方法将会抛出异常。可重入锁RLock对象也是一种常用的线程同步原语,可被同一个线程acquire()多次。当处于locked状态时,某线程拥有该锁;当处于unlocked状态时,该锁不属于任何线程。RLock对象的acquire() / release()调用对可以嵌套,仅当最后一个或者最外层的release()执行结束后,锁才会被设置为unlocked状态。
-
Condition对象介绍
Condition对象可以在某些事件触发后才处理数据,可以用于不同线程之间的通信或通知,以实现更高级别的同步。Condition对象除了具有acquire()和release()方法之外,还有wait()、notify()和notify_all()等方法。 -
Event对象介绍
Event对象是一种简单的线程通信技术,一个线程设置Event对象,另一个线程等待Event对象。Event对象的set()方法可以设置Event对象内部的信号标识为真;clear()方法可以清除Event对象内部信号标识,将其设置为假;isSet()方法用来判断其内部信号标识的状态;wait()方法只有在其内部信号状态为真时将很快地执行并返回,若Event对象的内部信号标识为假,wait()方法将一直等待至超时或内部信号状态为真。 -
简单例子
# 例 3-1
# 输出结果:打印10次以3为首项公差为3的等差数列。
import threading
import time
class mythread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global x
# 上锁
lock.acquire()
for i in range(3):
x = x + i
time.sleep(2)
print(x)
# 释放锁
lock.release()
lock = threading.RLock()
tlist = []
for i in range(10):
tlist.append(mythread())
x = 0
for t in tlist:
t.start()
# 例 3-2
import threading
class mythread(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self,name = name)
def run(self):
global myevent
# 如果myevent内部的信号量被设置了,则清除myevent内部信号量并阻塞该线程
# 否则打印该线程名字并且设置myevent内部信号量。
if myevent.isSet():
myevent.clear()
myevent.wait()
print(self.getName())
else:
print(self.getName())
myevent.set()
myevent = threading.Event()
myevent.set()
tlist = []
for i in range(10):
tlist.append(mythread(str(i)))
for t in tlist:
t.start()
来源:CSDN
作者:MagicOct
链接:https://blog.csdn.net/MagicOct/article/details/104128987