thread介绍
python提供多线程模块thread及threading,以及队列Queue,其中thread相对比较基础,不容易控制,但并不是说明无用,有些老司机偶尔会使用thead参看底层堆栈内存,官方建议使用threading模块,thread模块在python3版本中被重命名为_thread
Python解释器中可以同时运行多个线程,但是在任意时刻只能有一个线程在解释器运行。
Python虚拟机的访问是由全局解锁器(GIL)控制的,由GIL保证同时只有一个线程的运行。
执行方式如下:
设置GIL
切换到一个进程进行执行
执行下面操作中的一个
1.运行指定数量的字节码
2.线程主动出让控制权
将线程设置为睡眠状态,即切换出线程,比如使用sleep(0)
解锁GIL
loop
thread提供以下函数方法:
1.exception thread.error 异常
2.thread.LockType 锁类型
3.thread.start_new_thread(function, args[, kwargs]) 开始一个线程,function函数名称,以及args参数是必须的,如果函数本身没有传参,
则ye需要给args传入一个参数,例如()空列表就可以了,但传入参数时,需要在后面添加上逗号(,),例如thread.start_new_thread(hello, (“tom”,))
4.thread.interrupt_main() 终端main进程
5.thread.exit() 线程退出
6.thread.allocate_lock() 设置锁
7.thread.get_ident() 获取当前线程的标识符,是一个非零的整数
8.thread.stack_size([size]) 内存堆栈的大小,可以是0或大于32Kb的整数,如果大小无效则会抛出异常
注:
1.退出的方法 sys.exit() 或抛出 SystemExit异常
2.当主程序退出时,不论子线程是否执行完成,都会结束,没有线程守护
thread提供锁机制:
1.lock.acquire([waitflag]) 请求锁,waitflag是请求超时时间,如果为0,则表示立即能获得的,若为非零整数,则等待超时时间内获取
2.lock.release() 锁释放
3.lock.locked() 锁的状态
4.thread.allocate_lock() 加载锁
示例如下:
创建两个普通的函数,读书,听音乐
#coding=utf8
from time import ctime,sleep
def readbook(name="time"):
print "%s reading book : %s"%(ctime(),name)
sleep(2)
print "%s end read book"%(ctime())
def listenmusic(name="好汉歌"):
print "%s listening music : %s"%(ctime(),name)
sleep(5)
print "%s play music " % (ctime())
print "start--- %s"%(ctime())
readbook()
listenmusic()
print "end --- %s"%(ctime())
输出如下:
start--- Fri May 26 20:13:52 2017
Fri May 26 20:13:52 2017 reading book : time
Fri May 26 20:13:54 2017 end read book
Fri May 26 20:13:54 2017 listening music : 好汉歌
Fri May 26 20:13:59 2017 play music
end --- Fri May 26 20:13:59 2017
该段程序顺序执行,但是如果想要表示一边听着音乐一边看书,则无法做到
使用thread模块创建多线程,改进如下:
#coding=utf8
import thread
from time import ctime,sleep
def readbook(name="time"):
print "%s reading book : %s"%(ctime(),name)
sleep(2)
print "%s end read book"%(ctime())
def listenmusic(name="好汉歌"):
print "%s listening music : %s"%(ctime(),name)
sleep(5)
print "%s end play music " % (ctime())
print "start--- %s"%(ctime())
thread.start_new_thread(readbook,("oldman",))
thread.start_new_thread(listenmusic,("the sea",))
print "end --- %s"%(ctime())
注:
thread.start_new_thread(readbook,(“oldman”,))传入参数时,”oldman”,逗号是必须的
执行结果:
Unhandled exception in thread started by
start--- Fri May 26 22:20:12 2017
sys.excepthook is missing
end --- Fri May 26 22:20:12 2017Fri May 26 22:20:12 2017 reading book : oldman
lost sys.stderr
可以看到程序抛出异常,并且显示readbook程序刚执行就已经退出,这是thread的弊端,没有守护进程,主程序退出,子程序也被强制退出
若要正常执行完成,可以使用sleep等待时间:
修改为
print "start--- %s"%(ctime())
thread.start_new_thread(readbook,("oldman",))
thread.start_new_thread(listenmusic,("the sea",))
sleep(8)
print "end --- %s"%(ctime())
执行结果:
start--- Fri May 26 22:23:55 2017
Fri May 26 22:23:55 2017 reading book : oldman
Fri May 26 22:23:55 2017 listening music : the sea
Fri May 26 22:23:57 2017 end read book
Fri May 26 22:24:00 2017 end play music
end --- Fri May 26 22:24:03 2017
但是sleep的时间并不能一直都能计算准确,若计算失误,仍有可能出现异常
使用锁机制解决thread的退出异常
# coding=utf8
import thread
from time import sleep, ctime
import random
def readbook(lock,name="time", s=0):
print "%s reading book : %s" % (ctime(), name)
sleep(s)
print "%s end read book" % (ctime())
lock.release()
def listenmusic(lock,name="好汉歌", s=0):
print "%s listening music : %s" % (ctime(), name)
sleep(s)
print "%s end play music " % (ctime())
lock.release()
functions = ["readbook", "listenmusic"]
def main():
print 'the start : %s'%(ctime())
locks={}
for i in functions:
locks[i] = thread.allocate_lock()
locks[i].acquire()
thread.start_new_thread(readbook, (locks["readbook"],"man", random.randint(1, 5),))
sleep(0.1)
thread.start_new_thread(listenmusic, (locks["listenmusic"],"the sea", random.randint(1, 5),))
print thread.LockType
for i in functions:
while locks[i].locked():
pass
print "end --- %s" % (ctime())
if __name__ == '__main__':
main()
这里使用锁,然后进行while盲等待:
for i in functions:
while locks[i].locked():
pass
执行结果:
the start : Fri May 26 23:06:38 2017
Fri May 26 23:06:38 2017 reading book : man
<type 'thread.lock'>
Fri May 26 23:06:38 2017 listening music : the sea
Fri May 26 23:06:41 2017 end play music
Fri May 26 23:06:42 2017 end read book
end --- Fri May 26 23:06:42 2017
thread.LockType显示锁的类型:
<type 'thread.lock'>
本文介绍了Python中的thread模块,包括其基本功能和提供的函数方法,如start_new_thread、allocate_lock等。讨论了全局解释器锁(GIL)对多线程执行的影响。通过示例展示了如何使用锁来避免线程异常退出,解释了lock.acquire、lock.release等方法的作用。最后,通过实例演示了如何利用锁解决线程退出问题。
1799

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



