当前位置: 首页 > news >正文

Python模块-threading模块

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

threading

threading模块方法

方法释义
threading.Lock()互斥锁/同步锁
threading.RLock()递归锁
threading.Event()同步对象
threading.currentThread()返回当前的线程变量
threading.enumerate()返回一个包含正在运行的list。正在运行指线程启动后、结束前,不包含启动前和终止后的线程
threading.activeCount()返回正在运行的线程数量,与len(threading.enumerate())有相同结果

threading.Lock()

多线程示例 - 线程不安全

==错误示例【因所有线程多任务处理争夺处理器资源取初始化测试值造成结果错误!】==

# -*- coding:utf-8 -*--
import threading,time

num = 100                               #初始化测试值
def sub():                              #定义测试函数
    global num                              #引入测试值
    temp = num                              #测试值赋予新值
    time.sleep(0.001)                       #增加运行时间便于查看测试结果
    num = temp - 1                          #测试运算方式
l = []                                  #建立空列表便于添加线程对象
for i in range(100):                    #启用线程
    t = threading.Thread(target=sub)
    t.start()
    l.append(t)
for i in l:                             #遍历所有线程
    t.join()                            #守护主进程
print(num)                              #输出结果
95

错误示例解决方案 - 使用互斥锁-threading.Lock 相当于并行变串行

# -*- coding:utf-8 -*--
import threading,time

num = 100                               #初始化测试值
def sub():                              #定义测试函数
    global num                              #引入测试值
    lock.acquire()                          #获得同步锁,只允许一个线程使用处理器资源
    temp = num                              #测试值赋予新值
    time.sleep(0.001)                       #增加运行时间便于查看测试结果
    num = temp - 1                          #测试运算方式
    lock.release()                          #释放同步锁
l = []                                  #建立空列表便于添加线程对象
lock = threading.Lock()                 #建立同步锁
for i in range(100):                    #启用线程
    t = threading.Thread(target=sub)
    t.start()
    l.append(t)
for i in l:                             #遍历所有线程
    t.join()                            #守护主进程
print(num)                              #输出结果

0

threading.RLock()

死锁模拟,进程一直处于等待

# -*- coding:utf-8 -*-
import threading,time

class MyThread(threading.Thread):
    def actionA(self):
        A.acquire()                                                     #锁定 A 锁  第一个线程获得其它线程等待
        print("当前锁名称:",self.name,"当前时间:",time.ctime())
        time.sleep(2)

        B.acquire()                                                     #锁定 B 锁             第二个线程对B锁有需求,但B锁在第一个线程未释放,要等待第一个线程释放 【造成死锁】
        print("当前锁名称:", self.name, "当前时间:", time.ctime())
        time.sleep(1)

        B.release()                                                     #释放 B 锁
        A.release()                                                     #释放 A 锁   第一个线程释放,其他线程执行

    def actionB(self):
        B.acquire()                                                     #锁定 B 锁   第一个线程获得B锁,同一时刻下个进程获得A锁
        print("当前锁名称:",self.name,"当前时间:",time.ctime())
        time.sleep(2)

        A.acquire()                                                     #锁定 A 锁   第一个线程对A锁有需求,但A锁第二个线程未释放,要等待第二个线程释放    【造成死锁】
        print("当前锁名称:", self.name, "当前时间:", time.ctime())
        time.sleep(1)

        A.release()                                                     #释放 A 锁
        B.release()                                                     #释放 B 锁

    def run(self):                                                      #所有线程同时执行此方法
        self.actionA()
        self.actionB()
if __name__ == '__main__':
    A = threading.Lock()                        #创建 A 锁
    B = threading.Lock()                        #创建 B 锁
    L = []
    for i in range(5):                                                  #模拟创建5个线程
        t = MyThread()
        t.start()
        L.append(t)
    for i in L:
        i.join()
    print("程序结束!")
###### 注意:程序并未完成,处于一直等待释放阶段~ #########

当前锁名称: Thread-1 当前时间: Mon Jun  4 19:49:49 2018
当前锁名称: Thread-1 当前时间: Mon Jun  4 19:49:51 2018
当前锁名称: Thread-2 当前时间: Mon Jun  4 19:49:52 2018
当前锁名称: Thread-1 当前时间: Mon Jun  4 19:49:52 2018

用递归锁-threading.RLock() 避免死锁情况发生,线程未释放同名称锁别的线程无法获取锁处于等待中

# -*- coding:utf-8 -*-
import threading,time

class MyThread(threading.Thread):
    def actionA(self):
        R_Lock.acquire()                                                     #锁定 rlock 锁
        print("当前锁名称:",self.name,"当前时间:",time.ctime())
        time.sleep(2)

        R_Lock.acquire()                                                     #锁定 rlock 子锁
        print("当前锁名称:", self.name, "当前时间:", time.ctime())
        time.sleep(1)

        R_Lock.release()                                                     #释放 rlock 子锁
        R_Lock.release()                                                     #释放 rlock 锁

    def actionB(self):
        R_Lock.acquire()                                                     #锁定 rlock 锁
        print("当前锁名称:",self.name,"当前时间:",time.ctime())
        time.sleep(2)

        R_Lock.acquire()                                                     #锁定 rlock 子锁
        print("当前锁名称:", self.name, "当前时间:", time.ctime())
        time.sleep(1)

        R_Lock.release()                                                     #释放 rlock 子锁
        R_Lock.release()                                                     #释放 rlock 锁

    def run(self):                                                      #所有线程同时执行此方法
        self.actionA()
        self.actionB()
if __name__ == '__main__':
    # A = threading.Lock()
    # B = threading.Lock()
    R_Lock = threading.RLock()                    #创建 rlock 递归锁
    L = []
    for i in range(5):                                                  #模拟创建5个线程
        t = MyThread()
        t.start()
        L.append(t)
    for i in L:
        i.join()
    print("程序结束!")
当前锁名称: Thread-1 当前时间: Mon Jun  4 20:05:33 2018
当前锁名称: Thread-1 当前时间: Mon Jun  4 20:05:35 2018
当前锁名称: Thread-2 当前时间: Mon Jun  4 20:05:36 2018
当前锁名称: Thread-2 当前时间: Mon Jun  4 20:05:38 2018
当前锁名称: Thread-3 当前时间: Mon Jun  4 20:05:39 2018
当前锁名称: Thread-3 当前时间: Mon Jun  4 20:05:41 2018
当前锁名称: Thread-4 当前时间: Mon Jun  4 20:05:42 2018
当前锁名称: Thread-4 当前时间: Mon Jun  4 20:05:44 2018
当前锁名称: Thread-4 当前时间: Mon Jun  4 20:05:45 2018
当前锁名称: Thread-4 当前时间: Mon Jun  4 20:05:47 2018
当前锁名称: Thread-1 当前时间: Mon Jun  4 20:05:48 2018
当前锁名称: Thread-1 当前时间: Mon Jun  4 20:05:50 2018
当前锁名称: Thread-2 当前时间: Mon Jun  4 20:05:51 2018
当前锁名称: Thread-2 当前时间: Mon Jun  4 20:05:53 2018
当前锁名称: Thread-3 当前时间: Mon Jun  4 20:05:54 2018
当前锁名称: Thread-3 当前时间: Mon Jun  4 20:05:56 2018
当前锁名称: Thread-5 当前时间: Mon Jun  4 20:05:57 2018
当前锁名称: Thread-5 当前时间: Mon Jun  4 20:05:59 2018
当前锁名称: Thread-5 当前时间: Mon Jun  4 20:06:00 2018
当前锁名称: Thread-5 当前时间: Mon Jun  4 20:06:02 2018
程序结束!

threading.Event()

事件Event同步线程

名称释义
event.isSet()返回event状态值False或True
event.wait()如果event状态为False,将阻塞线程
event.set()默认设定event为True
event.clear()恢复event的状态为False

示例:

# -*- coding:utf-8 -*-
import threading,time

class Boss(threading.Thread):
    def run(self):
        print("BOSS:今天晚上加班到22:00")
        print("event.set【设定前】event状态:",event.isSet())
        event.set()                                     #【阻塞】         -       设定event.set标志位
        print("event.set【设定后】event状态:", event.isSet())
        #等待阻塞状态清空后才可以执行以下代码
        time.sleep(5)
        print("BOSS:现在可以下班了!!!")
        event.set()
class Worker(threading.Thread):
    def run(self):
        event.wait()                                    #【阻塞】         -       标志位被设定
        print("员工:命真苦~")
        event.clear()                                   #【清空状态】     -       阻塞状态清空
        event.wait()                                    #【阻塞】         -       标志位被设定
        print("员工:解放了!")
if __name__ == '__main__':
    event = threading.Event()                            #创建Event对象
    L = []
    for i in range(3):                                   #建立多线程
        L.append(Worker())
    L.append(Boss())
    for t in L:                                          #启用多线程
        t.start()
    for t in L:                                          #等待线程
        t.join()
    print("end")
BOSS:今天晚上加班到22:00
event.set【设定前】event状态: False
event.set【设定后】event状态: True
员工:命真苦~
员工:命真苦~
员工:命真苦~
BOSS:现在可以下班了!!!
员工:解放了!
员工:解放了!
员工:解放了!
end

转载于:https://my.oschina.net/zhaojunhui/blog/1824307

相关文章:

  • xtrabackup 备份原理
  • tkinter简单打开网址 + 执行系统命令
  • flask学习笔记之flask-migrate
  • 项目实战 (规范、轮子、学习案例) - iOS
  • iOS中类、元类、isa详解
  • 生鲜 B2B 平台的产品体系如何迭代(B2B 技术共享第三篇)
  • CentOS7.X安装php-7.x.x
  • 2018年UI设计师的前景如何?长沙牵引力用数据告诉你
  • JS深拷贝总结
  • centos7安装
  • 万万没想到,枯燥的“机器学习”还可以这样学!
  • 被忽略的对象
  • Xtrabackup 使用stream输出并压缩备份
  • 一个UPDATE语句引发的血案
  • 机器学习中为什么要做归一化normalization
  • 【技术性】Search知识
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • egg(89)--egg之redis的发布和订阅
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • leetcode讲解--894. All Possible Full Binary Trees
  • Lsb图片隐写
  • RxJS: 简单入门
  • vue自定义指令实现v-tap插件
  • Web设计流程优化:网页效果图设计新思路
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 初识 webpack
  • 当SetTimeout遇到了字符串
  • 聊一聊前端的监控
  • 七牛云假注销小指南
  • 浅谈Golang中select的用法
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 算法-图和图算法
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 微信开放平台全网发布【失败】的几点排查方法
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • 1.Ext JS 建立web开发工程
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • ​iOS安全加固方法及实现
  • #控制台大学课堂点名问题_课堂随机点名
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (Git) gitignore基础使用
  • (vue)页面文件上传获取:action地址
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (三)uboot源码分析
  • (十一)c52学习之旅-动态数码管
  • (算法二)滑动窗口
  • (转)JAVA中的堆栈
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .NET MVC第五章、模型绑定获取表单数据