0x00:thread模块
函数 / 方法 | 描述 |
---|---|
thread 模块的函数 | |
start_new_thread(function,args,kwargs=None) | 派生一个新的线程,使用给定的args和可选的 kwargs 来执行 function |
allocate_lock() | 分配LockType 锁对象 |
exit() | 线程退出指令 |
LockType 锁对象的方法 | |
acquire(wait=None) | 尝试获取锁对象 |
locked() | 如果获取了锁对象则返回True,否则返回 False |
release() | 释放锁 |
import _thread # 导入线程模块
from time import ctime,sleep #导入时间戳和睡眠模块
loops = [4,2] #把常量放到列表中
def loop(nloop,nsec,lock): #定义 loop 函数
print("start loop",nloop , 'at:' , ctime()) # 打印开始 loop
sleep(nsec) #睡眠 nesc 秒
print('aa', nloop , 'dont at:' ,ctime()) # 打印 loop nloop
lock.release()
def main(): # 定义main 函数z
print('strting at: ', ctime()) # 打印开始的事件
locks = [] #定义锁的列表
nloops = range(len(loops)) # 获取 locks列表的长度
for i in nloops: # 定义for循环
lock = _thread.allocate_lock() # 分配locks锁的对象
lock.acquire() # 尝试获取锁 lock的对象, 一旦锁被锁上后,就把锁添加到列表中
locks.append(lock) #把锁添加到 lock列表中
for i in nloops: # 创建循环用于派生线程
_thread.start_new_thread(loop, (i, loops[i],locks[i])) # 这个循环会调用loop 函数, 传递循环信号、睡眠时间以及用于该线程锁的几个参数
for i in nloops: # 定义一个循环
while locks[i].locked(): #如果获取了锁的对象,就返回True,不然就是flase
pass
print('all Done at: ',ctime())
if __name__ == '__main__':
main() #调用 main 函数
运行结果:
E:\Python3\python3.exe E:/pythonProject/thred线程模块.py
strting at: Wed Jul 28 22:57:27 2021
start loop 1 at: Wed Jul 28 22:57:27 2021
start loop 0 at: Wed Jul 28 22:57:27 2021
aa 1 dont at: Wed Jul 28 22:57:29 2021
aa 0 dont at: Wed Jul 28 22:57:31 2021
all Done at: Wed Jul 28 22:57:31 2021
注意事项
_thread对于进程何时退出没有任何控制。当主线程结束时,所有其他线程也都强制结束。不会发出警告或者进行适当的清理。因而python多线程一般使用较为高级的threading模块,它提供了完整的线程控制机制以及信号量机制。
0x01:threading 模块
对象 | 描述 |
---|---|
Thread | 表示一个执行线程的对象 |
Lock | 锁原语对象 |
RLokc | 可重入锁对象,使得一个线程等待另一个线程满足特定的条件,比如改变状态或者某个值 |
Condition | 条件变量对象,使用一个线程等待另一个线程满足某个事件的发送,在该事件发生后,线程将被激活 |
Event | 条件变量的通用版本,任意数量的线程等待某个事件的发生,在该事件发生后,线程将被激活 |
Semaphore | 为线程间共享提供了一个计数器,如果没有可用资源会被阻塞 |
BoundedSemaphore | 与Semaphore类似,不过它不允许超过初始值 |
Timer | 与Thread 相似,不过他要在运行前等待一段时间 |
Barrier | 创建一个障碍,必须达到指定数量的线程后才可以继续 |
函数 / 方法 | 描述 |
---|---|
thread 对象数据属性 | |
name | 线程名 |
ident | 线程的标识符 |
daemon | 布尔标志,表示这个线程是否是守护线程 |
Thread 对象方法 | |
init(group=None,target=None,name=None,args=None,kwargs=None,daemom) | 实例化一个线程对象,需要一个可以调用的 target ,以及其参数 args 或 kwargs |
strat() | 开始执行该线程 |
run() | 定义线程的方法 |
join(timeout=None) | 直至启动的线程终止之前一直挂起,除非给出了timeout秒,否则会一直阻塞 |
getName() | 返回线程名 |
setName() | 设置线程名 |
isAlivel/ is_alive() | 布尔标志,标志这个线程是否存活 |
isDaemmon(0 | 如果是守护线程,返回True, 否则返回 false |
setDaemmon() | 把线程的守护标志设置为布尔值(必须在线程开始之前调用) |
(1)创建一个 thread的实例,传给他一个函数
在这个例子中,我们只是把Thread 类实例化,然后将函数(及其参数)传递进去。当线程开始执行时,函数也会执行。
import threading # 导入 theading 模块
from time import ctime,sleep # 导入时间、睡眠模块
loops = [4,2] # 定义一个列表,睡眠的时间
def loop(nloop,nesc): # 创建一个函数
print("start loo", nloop ,'at:',ctime())
sleep(nesc) # 睡眠 nesc 秒
print("start loo", nloop ,'done at:',ctime())
def main(): # 定义 一个 main 主函数
print("start at:",ctime()) # 打印 开始的到时间
threads = [] # 创建一个空列表
nloops = range(len(loops)) # nloops 等于 0,1
for i in nloops: # 创建一个 for 循环 ,取 nloops的值
t = threading.Thread(target=loop,args=(i, loops[i])) # 创建一个执行线程的对象,传给它的一个函数
threads.append(t) # 把线程的执行对象添加 theands 列表中
for i in nloops: # 创建一个 for 循环
threads[i].start() # 开始执行线程
for i in nloops: # 创建一个 for 循环
threads[i].join() # 为每个子线程 调用join方法,等待线程结束
print("all Done at:",ctime()) # 打印输出语句
if __name__ =='__main__':
main()
join()方法等待线程结束,或者在提供了超时时间的情况下,达到超时时间。 join方法不需要调用,一旦线程开始,就会立即执行,知道给定的函数完成后退出。
(2)创建thread的实例,传给它一个可以调用的类实例
在创建线程时,与传入函数相似的一个方法就是传入一个可以调用的类的实例用于线程执行。 这种可调用的类包含一个执行环境,从一个函数或者从一组函数中选择而言,有更好的灵活性。
import threading # 导入 theading 模块
from time import ctime,sleep # 导入时间、睡眠模块
loops = [4,2] # 定义一个列表,睡眠的时间
class TheadFunc(object): # 创建一个类
def __init__(self,func,args,name=''): #初始化 init ,实例化一个对象
self.name = name # 赋值
self.func = func
self.args = args
def __call__(self): #使用call方法,回调函数
self.func(*self.args)
def loop(nloop,nsec): #定义一个函数
print("start loop", nloop, 'at:',ctime())
sleep(nsec) # 定义睡眠得时间
print("sloop", nloop, 'done at:',ctime())
def main(): # 定义一个main 函数
print("starting at:",ctime())
threads = [] # 创建一个列表
nloops = range(len(loops)) # 复制一个range,子线程数量
for i in nloops:
t = threading.Thread(
target=TheadFunc(loop, (i, loops[i]),loop.__name__)) # 实例化线程的 Thread 对象, 这个很有意思
threads.append(t)
for i in nloops:
threads[i].start() # 开其线程
for i in nloops:
threads[i].join() # 等待线程结束
print("all DONE at:",ctime())
if __name__ =='__main__':
main()
(3)派生 Thread 的子类,并创建子类的实例
import threading # 导入 theading 模块
from time import ctime,sleep # 导入时间、睡眠模块
loops = [4,2] # 定义一个列表,睡眠的时间
class MyThread(threading.Thread): #创建一个 Thread子类
def __init__(self,func,args,name=""): #初始化 init ,实例化一个对象
threading.Thread.__init__(self)
self.name = name
self.func = func
self.args = args
def run(self): # 运行func这个函数
self.func(*self.args)
def loop(nloop,nesc):
print("start loop", nloop, 'at:',ctime())
sleep(nesc) # 定义睡眠得时间
print("sloop", nloop, 'done at:',ctime())
def main():
print("starting at:",ctime())
threads = [] # 创建一个列表
nloops = range(len(loops)) # 复制一个range,子线程数量
for i in nloops:
t = MyThread(loop, (i, loops[i]),loop.__name__) # 实例化线程的 Thread 对象, 这个很有意思
threads.append(t)
for i in nloops:
threads[i].start() # 开其线程
for i in nloops:
threads[i].join() # 等待线程结束
print("all DONE at:",ctime())
if __name__ =='__main__':
main()