当前位置:
首页 > Python基础教程 >
-
Python3标准库:threading进程中管理并发操作(3)
',
)
for i in range(3):
t = threading.Thread(target=worker, daemon=True)
t.start()
main_thread = threading.main_thread()
for t in threading.enumerate():
if t is main_thread:
continue
logging.debug('joining %s', t.getName())
t.join()
由于工作线程睡眠的时间量是随机的,所以这个程序的输出可能有变化。
1.5 派生线程
开始时,Thread要完成一些基本初始化,然后调用其run()方法,这会调用传递到构造函数的目标函数。要创建Thread的一个子类,需要覆盖run()来完成所需的工作。
- import threading
- import logging
- class MyThread(threading.Thread):
- def run(self):
- logging.debug('running')
- logging.basicConfig(
- level=logging.DEBUG,
- format='(%(threadName)-10s) %(message)s',
- )
- for i in range(5):
- t = MyThread()
- t.start()
run()的返回值将被忽略。
由于传递到Thread构造函数的args和kwargs值保存在私有变量中(这些变量名都有前缀),所以不能很容易地从子类访问这些值。要向一个定制的线程类型传递参数,需要重新定义构造函数,将这些值保存在子类可见的一个实例属性中。
- import threading
- import logging
- class MyThreadWithArgs(threading.Thread):
- def __init__(self, group=None, target=None, name=None,
- args=(), kwargs=None, *, daemon=None):
- super().__init__(group=group, target=target, name=name,
- daemon=daemon)
- self.args = args
- self.kwargs = kwargs
- def run(self):
- logging.debug('running with %s and %s',
- self.args, self.kwargs)
- logging.basicConfig(
- level=logging.DEBUG,
- format='(%(threadName)-10s) %(message)s',
- )
- for i in range(5):
- t = MyThreadWithArgs(args=(i,), kwargs={'a': 'A', 'b': 'B'})
- t.start()
MyThreadwithArgs使用的API与Thread相同,不过类似于其他定制类,这个类可以轻松地修改构造函数方法,以取得更多参数或者与线程用途更直接相关的不同参数。
1.6 定时器线程
有时出于某种原因需要派生Thread,Timer就是这样一个例子,Timer也包含在threading中。Timer在一个延迟之后开始工作,而且可以在这个延迟期间内的任意时刻被取消。
- import threading
- import time
- import logging
- def delayed():
- logging.debug('worker running')
- logging.basicConfig(
- level=logging.DEBUG,
- format='(%(threadName)-10s) %(message)s',
- )
- t1 = threading.Timer(0.3, delayed)
- t1.setName('t1')
- t2 = threading.Timer(0.3, delayed)
- t2.setName('t2')
- logging.debug('starting timers')
- t1.start()
- t2.start()
- logging.debug('waiting before canceling %s', t2.getName())
- time.sleep(0.2)
- logging.debug('canceling %s', t2.getName())
- t2.cancel()
- logging.debug('done')
这个例子中,第二个定时器永远不会运行,看起来第一个定时器在主程序的其余部分完成之后还会运行。由于这不是一个守护线程,所以在主线程完成时其会隐式退出。
1.7 线程间传送信号
尽管使用多线程的目的是并发地运行单独的操作,但有时也需要在两个或多个线程中同步操作。事件对象是实现线程间安全通信的一种简单方法。Event管理一个内部标志,调用者可以用set()和clear()方法控制这个标志。其他线程可以使用wait()暂停,直到这个标志被设置,可有效地阻塞进程直至允许这些线程继续。
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式