threading和_thread创建多线程
本篇可看文字,别看代码,代码太多,看着有复用的就拿走
具体的来源;太多文字描述了,最后还有糖果机和生产队列实例,实在弄不清楚应用的地方
threading模块多线程创建的两种方法
首先他有两种创建多线程的方法,一般都是选threading模块,而另外一种是_thread模块,是为了延续python中的thread模块
threading模块创建多线程有两个方法,第一个是使用threading.Thread类,想该类中传入函数(关键字target),还有函数的参数(关键字args),就算函数没有参数也必须写上空元组。然后再把该类传入的对象赋值给一个变量该变量使用start()函数启动线程,若是多个函数,可使用join()函数()确保两个线程结束运行。
使用threading.Thread类
import threading
'''
在threading模块中,除包含"_thread"模块中的所有方法之外,还提供了如下的核心方法
.currentThread():返回当前的Thread对象,这是一个线程变量
.enumerate:返回一个包含正在运行的线程的列表
.activeCount():返回正在运行的线程数量
.main_thread():返回主thread对象。正常情况下,主线程是从python解释器中启动的线程
settrace(func):为所有从threading模块启动的线程设置一个跟踪方法。在每个线程的run()方法调用之前,func将传递给sys.settrace()
.setprofile(func):为所有从threading模块启动的线程设置一个profile()方法
还提供.TIMEOUT_MAX,该方法表示阻塞方法允许等待的最长时限,设置超过此值的超时将会引发OverflowError
'''
from time import sleep, ctime
# 线程函数,index表示整数类型的索引,sec表示休眠时间,单位:秒
def fun(index, sec):
print('开始执行', index, ' 时间:', ctime())
# 休眠sec秒
sleep(sec)
print('结束执行', index, '时间:', ctime())
def main():
# 创建第1个Thread对象,通过target关键字参数指定线程函数fun,传入索引10和休眠时间(4秒)
thread1 = threading.Thread(target=fun,
args=(10, 4))
# 启动第1个线程
thread1.start()
# 创建第2个Thread对象,通过target关键字参数指定线程函数fun,传入索引20和休眠时间(2秒)
thread2 = threading.Thread(target=fun,
args=(20, 2))
# 启动第2个线程
thread2.start()
# 等待第1个线程函数执行完毕
thread1.join()
# 等待第2个线程函数执行完毕
thread2.join()
if __name__ == '__main__':
main()
另外一种方式是类的构造(threading.Thread)
重写该类中的run()方法
但具体调用的函数命名也就必须为run()了
import threading
from time import sleep, ctime
# 从Thread类派生的子类
class MyThread(threading.Thread):
# 重写父类的构造方法,其中func是线程函数,args是传入线程函数的参数,name是线程名
def __init__(self, func, args, name=''):
# 调用父类的构造方法,并传入相应的参数值
super().__init__(target=func, name=name,
args=args)
# 重写父类的run方法
def run(self):
self._target(*self._args)
# 线程函数
def fun(index, sec):
print('开始执行', index, '时间:', ctime())
# 休眠sec秒
sleep(sec)
print('执行完毕', index, '时间:', ctime())
def main():
print('开始:', ctime())
# 创建第1个线程,并指定线程名为“线程1”
thread1 = MyThread(fun, (10, 4), '线程1')
# 创建第2个线程,并指定线程名为“线程2”
thread2 = MyThread(fun, (20, 2), '线程2')
# 开启第1个线程
thread1.start()
# 开启第2个线程
thread2.start()
# 输出第1个线程的名字
print(thread1.name)
# 输出第2个线程的名字
print(thread2.name)
# 等待第1个线程结束
thread1.join()
# 等待第2个线程结束
thread2.join()
print('结束:', ctime())
if __name__ == '__main__':
main()
_thread模块有的方法,threading模块都有
其实threading是在_thread基础上建立的,_thread创建多线程虽然也是使用类对象,但并不是使用start()函数启动线程,而是使用start_new_thread()函数启动线程,具体启用多少个线程可以使用for循环
import random
from time import sleep
import _thread as thread
# 线程函数,其中a和b是通过start_new_thread函数传入的参数
def fun(a,b):
print(a,b)
# 随机休眠一个的时间(1到4秒)
sleep(random.randint(1,5))
'''
print()函数的执行结果;可以得知该多线程是无序的
1 a
4 aaaa
2 aa
5 aaaaa
8 aaaaaaaa
6 aaaaaa
3 aaa
7 aaaaaaa
'''
# 启动8个线程
for i in range(8):
# 为每一个线程函数传入2个参数值
thread.start_new_thread(fun, (i + 1,'a' * (i + 1)))
# 通过从终端输入一个字符串的方式让程序暂停
input() # 去掉该input函数,就不会将print()函数的内容打印在终端
另外一个实例
import _thread as thread
'''
thread原本是python2中的模块,在python3中被threading替换,但为了兼容python2的程序,在
python3中将thread模块重命名为"_thread"
'''
from time import sleep, ctime
def fun1():
print('开始运行fun1:', ctime())
# 休眠4秒
sleep(4)
print('fun1运行结束:', ctime())
def fun2():
print('开始运行fun2:', ctime())
# 休眠2秒
sleep(2)
print('fun2运行结束:', ctime())
def main():
print('开始运行时间:', ctime())
# 启动一个线程运行fun1函数
thread.start_new_thread(fun1, ())
'''
start_new_thread()函数的第二个参数必须是元组,第一个参数必须是线程函数
'''
# 启动一个线程运行fun2函数
thread.start_new_thread(fun2, ())
# 休眠6秒
sleep(6)
print('结束运行时间:', ctime())
if __name__ == '__main__':
main()
'''
在锁定对象_thread中包含如下方法
lock.acquire(waitflag=1,timeout=-1):里面的是参数值设置,如果设置了第一个参数,那么将依赖该参数的值:如果该参数为0,则
锁不等待且立即返回;不为0,则锁无条件的等待。
第二个参数的值若大于0,则指定等待的最大秒数,若参数为负数,则表示永久等待,如果第一个参数为0,则无法设置第二个参数。(一般情况下都不设置参数,一次仅一个线程能获取锁)
lock.release():释放锁。锁必须早已获取,但不一定由同一线程获取
lock.locked():返回锁的状态,True表示以被某个线程获取,False表示没有被某个线程获取
'''
努力拼搏吧,不要害怕,不要去规划,不要迷茫。但你一定要在路上一直的走下去,尽管可能停滞不前,但也要走。