python 多线程的使用笔记

1、多线程的基本用法

(1)简单任务多线程的开启方式

from threading import Thread
import timedef target(name, n):for i in range(0, n, 2):print(f'{name}_{i}')time.sleep(1)t1 = Thread(target=target, args=('a', 16, ))
t1.start()for i in range(1, 11, 2):print(f'主线程_{i}')time.sleep(1)

(2)自定义复杂任务多线程的开启方式,适合复杂逻辑

from threading import Thread
import timeclass myThread(Thread):def __init__(self, name, n):super(myThread, self).__init__()self.name = nameself.n = ndef run(self):for i in range(0, self.n, 2):print(f'{self.name}_{i}')time.sleep(1)t1 = myThread('a', 16, )
t1.start()for i in range(1, 11, 2):print(f'主线程_{i}')time.sleep(1)

2、关于守护线程和 join

正常情况下主线程和子线程可以相互没有干扰,独立运行完后程序结束

当我们需要主线程结束后子线程也随着结束,可以将子线程设置为守护线程后,这样主线程结束后,即便子线程没有运行完,子线程也会随着主线程结束
这里注意的是,子线程设置守护线程一定要在子线程开始之前

当我们需要子线程运行完主线程再接着往下运行时,子线程可以调用 join() 方法, 主线程就会等待,直到子线程终止或者超时才会继续往下执行
这里注意的是,子线程 join() 一定要在子线程开始之后
jion() 里面可以传入 timeout 参数,超时后主线程会继续往下运行
下面是 setDaemo()join() 的例子 可以去掉注释看看有什么不同

from threading import Thread
import timedef target(name, n):for i in range(0, n, 2):print(f'{name}_{i}')time.sleep(1)t1 = Thread(target=target, args=('a', 16,))
# t1.setDaemon(True)
t1.start()
# t1.join()for i in range(1, 11, 2):print(f'主线程_{i}')time.sleep(1)

3、关于信号量 Semaphore()BoundedSemaphore()

我们可以一次开启很多线程,但是我们想对同时运行的线程控制在一定数量内,开启的线程大于同时运行的线程时,其他的线程就处于阻塞状态,直到有线程运行结束,阻塞的线程才能开始运行,这时我们就用到 Semaphore() ,
信号量基于内部计数器,初始化 Semaphore() 时会给计数器一个值,每调用一次acquire(),计数器减1,每调用一次release(), 计数器加1,当计数器为0时,acquire()调用被阻塞

from threading import Thread, Semaphore
import timesema = Semaphore(3)def target(name, n):sema.acquire()for i in range(0, n, 2):print(f'{name}_{i}')time.sleep(1)sema.release()sema = Semaphore(3)for s in 'abcde':Thread(target=target, args=(s, 6,)).start()

Semaphore() 支持上下文,对于上面代码,也可以这样写

from threading import Thread, Semaphore
import timesema = Semaphore(3)def target(name, n):with sema:for i in range(0, n, 2):print(f'{name}_{i}')time.sleep(1)sema = Semaphore(3)for s in 'abcde':Thread(target=target, args=(s, 6,)).start()

BoundedSemaphore 继承自 Semaphore 功能和 Semaphore基本一样,只不过 BoundedSemaphore有限制,release()时会判断当前信号量的值,如果当前值大于等于初始值,就会抛出错误,而Semaphore并不会抛出异常

4 锁 LockRLock

如果运行上面代码,我们会发现,多个子线程之间可能打印在一行上,比较混乱,这是由于线程之间随机调度,同时输出。如果是同时在修改一个变量。或者一个文件,就有可能造成数据错误,这时互斥锁Lock就派上用场了。Lock可以用于锁定资源,Lock有两个基本方法,acquire()release(),调用acquire()状态变为锁定并立即返回,当状态是锁定时, acquire()将阻塞至其他线程调用 release() 将其改为非锁定状态,然后 acquire() 调用重置其为锁定状态并返回。锁支持上下文管理协议,即支持with语

from threading import Thread, Lock
import timelock = Lock()def target(name, n):for i in range(0, n, 2):lock.acquire()print(f'{name}_{i}')lock.release()time.sleep(1)for s in 'abcde':Thread(target=target, args=(s, 6,)).start()

with语句代替

from threading import Thread, Lock
import timelock = Lock()def target(name, n):for i in range(0, n, 2):with lock:print(f'{name}_{i}')time.sleep(1)for s in 'abcde':Thread(target=target, args=(s, 6,)).start()

如果尝试释放一个非锁定的锁,则会引发 RuntimeError 异常
RLock被称为重入锁,若要锁定锁,线程调用其 acquire() 方法;一旦线程拥有了锁,方法将返回。若要解锁,线程调用 release() 方法。 acquire()/release() 对可以嵌套,重入锁必须由获取它的线程释放。一旦线程获得了重入锁,同一个线程再次获取它将不阻塞。只有最终release() (最外面一对的 release() ) 将锁解开,才能让其他线程继续处理 acquire()阻塞,线程必须在每次获取它时释放一次。
LockRLock 用法大体相同,区别在于Lock在锁定时不属于特定线程,也就是说,Lock可以在一个线程中上锁,在另一个线程中解锁。而对于RLock来说,只有当前线程才能释放本线程上的锁,即解铃还须系铃人。

5 Event 事件

Event内部定义了一个标志位flag,初始的时候为False,当Flag的值为False,那么event.wait()就会阻塞,当flag值为True,那么event.wait()便不再阻塞Event主要提供以下方法
set()来将其设置为True
clear()将其重新设置为False
is_set()来检查标志位的状态;
wait(timeout=None),会一直监听flag,如果flagFalse就一直处于阻塞状态

from threading import Thread, Event
import timeclass myThread(Thread):def __init__(self, name, n):super(myThread, self).__init__()self.name = nameself.n = nself.e = Event()def pause(self): # 暂停self.e.clear()def play(self): # 继续self.e.set()def run(self):for i in range(0, self.n, 2):self.e.wait()print(f'{self.name}_{i}')time.sleep(1)t1 = myThread('a', 16, )
t1.play()
t1.start()for i in range(1, 11, 2):print(f'主线程_{i}')time.sleep(1)if i == 3:t1.pause() # 子线程暂停if i == 7:t1.play() # 子线程继续

特别感谢下面两篇文章的作者,供大家做参考学习
python多线程详解(超详细)
python threading模块的Lock和RLock区别

Python 多线程、守护进程、同时运行最大线程数、锁、线程阻塞(线程暂停和继续)相关推荐

  1. python多线程守护线程_Python守护程序线程

    python多线程守护线程 In this tutorial we will be learning about Python Daemon Thread. In our previous tutor ...

  2. python实现守护进程_守护进程原理及Python实现

    守护进程原理及Python实现 守护进程,不依赖于终端,在后台运行的程序,通常称为daemon(ˈdiːmən或ˈdeɪmən). 一些常见的Linux软件通常都是已守护进程的方式运行,比如: ngi ...

  3. 守护进程与后台进程(Python 创建守护进程)

    文章目录 一.守护进程与后台进程 1. 守护进程 1.1 代码实现 为什么要fork两次 umask权限掩码 进程组 会话组 2. 后台进程 3. 守护进程与后台进程区别 4. 使用场景总结 二.参考 ...

  4. python统计csv行数_对Python 多线程统计所有csv文件的行数方法详解

    如下所示: #统计某文件夹下的所有csv文件的行数(多线程) import threading import csv import os class MyThreadLine(threading.Th ...

  5. 一文详解java线程池 详解Java线程池的七个参数 详解池化技术 java如何选择核心线程数 详解Java线程池的拒绝策略

    目录 引言 线程池使用场景 加快请求响应(响应时间优先) 加快处理大任务(吞吐量优先) 特殊说明 线程池的池化技术 线程池的创建 手动创建 创建newFixedThreadPool线程池 创建newS ...

  6. Linux最大线程数限制及当前线程数查询

    Linux最大线程数限制及当前线程数查询 1.总结系统限制有: /proc/sys/kernel/pid_max #查系统支持的最大线程数,一般会很大,相当于理论值 /proc/sys/kernel/ ...

  7. Day9 - Python 多线程、进程 --转自金角大王

    本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者 ...

  8. 怎样利用Python制作守护进程

    有时候我们的需要制作一些守护进程,如果服务器出现了什么问题,就需要重启某个软件啊之类的 那么这类守护进程怎么做呢? 请看代码 import time seconds_to_sleep = 2 * 60 ...

  9. python实现守护进程_Python如何实现守护进程的方法示例

    Python如何实现守护进程的方法示例 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  Python如何实现守护进程的方法示例.txt ] (友情提示:右键点上行t ...

  10. python fork 守护进程

    # -*-coding:utf-8-*- import sys, os'''将当前进程fork为一个守护进程注意:如果你的守护进程是由inetd启动的,不要这样做!inetd完成了所有需要做的事情,包 ...

最新文章

  1. vlfeat 特征检测
  2. java 获取活动窗口_用Java获取活动窗口信息
  3. 杜克大学出来的NBA球星有哪些?
  4. mint-ui 中 Infinite scroll 在tab-container中使用数据全部加载的问题
  5. 如何打开Tango的ADF文件?
  6. SpringBoot 自带工具类~断言
  7. C语言 · 龟兔赛跑预测
  8. 教授先生带你学习链表:链表节点的删除与增添2
  9. Linux下,Pycharm到期,源不好使,无法安装pyqt5及pyqy5-tools的解决办法
  10. php nsdata,转换NSArray- JSON- NSData- PHP服务器- JSON表示
  11. 【教程搬运】廖雪峰Git的使用教程(一)
  12. 使用Windows批处理文件递归删除当前路径下的指定文件夹
  13. 2022年来啦!丨新年回馈粉丝丨免费抽奖!
  14. Web防火墙(WAF)是什么?和传统防火墙区别是什么?
  15. 详细前端面试题javascript篇--持续更新
  16. mybatis lazyload
  17. vue组件间通信六种方式
  18. Spring Boot与Elasticsearch的对应版本
  19. 高考投档计算机检索,高考志愿投档
  20. 第0章 计算机硬件与组成基础

热门文章

  1. 西安高端的软装设计公司
  2. 公积金和工资是按比例发放吗?
  3. 一种自动化生成骨架屏的方案
  4. 应届生找工作时除了薪酬还需要考虑什么
  5. 网格画法:react-konva 画网格,可拖动、可放大缩小、并带有坐标系 0 0 位置辅助线
  6. 【面试】 CVTE 视源股份 C++ 软件开发 一面
  7. [Tensorflow 2] LSTM
  8. 如何做到4小时以上的长时间精神专注?
  9. 区块链中的薅羊毛,你被薅了吗
  10. DBCO-amine Cas:1255942-06-3,DBCO-NH2,二苯基环辛炔-氨基可衍生DBCO-PEG-NH2