您的位置:首页 > 编程语言 > Python开发

python多线程模块thread

2017-05-26 23:49 513 查看

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