python多线程模块thread

本文介绍了Python中的thread模块,包括其基本功能和提供的函数方法,如start_new_thread、allocate_lock等。讨论了全局解释器锁(GIL)对多线程执行的影响。通过示例展示了如何使用锁来避免线程异常退出,解释了lock.acquire、lock.release等方法的作用。最后,通过实例演示了如何利用锁解决线程退出问题。
部署运行你感兴趣的模型镜像
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'>

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值