python3多线程第三方库_Python3 多线程

Python3 多线程

多线程类似于同时执行多个不同程序,多线程运行有如下优点:

使用线程可以把占据长时间的程序中的任务放到后台去处理。

用户界面可以更加吸引人,比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。

程序的运行速度可能加快。

在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。

指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。

线程可以被抢占(中断)。

在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) -- 这就是线程的退让。

线程可以分为:

内核线程:由操作系统内核创建和撤销。

用户线程:不需要内核支持而在用户程序中实现的线程。

Python3 线程中常用的两个模块为:

_thread

threading(推荐使用)

thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用"thread" 模块。为了兼容性,Python3 将 thread 重命名为 "_thread"。

开始学习Python线程

Python中使用线程有两种方式:函数或者用类来包装线程对象。

函数式:调用 _thread 模块中的start_new_thread()函数来产生新线程。语法如下:

_thread.start_new_thread ( function, args[, kwargs] )

参数说明:

function - 线程函数。

args - 传递给线程函数的参数,他必须是个tuple类型。

kwargs - 可选参数。

实例

#!/usr/bin/python3

import _thread

import time

# 为线程定义一个函数

def print_time( threadName, delay):

count = 0

while count < 5:

time.sleep(delay)

count += 1

print ("%s: %s" % ( threadName, time.ctime(time.time()) ))

# 创建两个线程

try:

_thread.start_new_thread( print_time, ("Thread-1", 2, ) )

_thread.start_new_thread( print_time, ("Thread-2", 4, ) )

except:

print ("Error: 无法启动线程")

while 1:

pass

执行以上程序输出结果如下:

Thread-1: Wed Apr 6 11:36:31 2016

Thread-1: Wed Apr 6 11:36:33 2016

Thread-2: Wed Apr 6 11:36:33 2016

Thread-1: Wed Apr 6 11:36:35 2016

Thread-1: Wed Apr 6 11:36:37 2016

Thread-2: Wed Apr 6 11:36:37 2016

Thread-1: Wed Apr 6 11:36:39 2016

Thread-2: Wed Apr 6 11:36:41 2016

Thread-2: Wed Apr 6 11:36:45 2016

Thread-2: Wed Apr 6 11:36:49 2016

执行以上程后可以按下 ctrl-c 退出。

线程模块

Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。

_thread 提供了低级别的、原始的线程以及一个简单的锁,它相比于 threading 模块的功能还是比较有限的。

threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:

threading.currentThread(): 返回当前的线程变量。

threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。

threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:

run(): 用以表示线程活动的方法。

start():启动线程活动。

join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。

isAlive(): 返回线程是否活动的。

getName(): 返回线程名。

setName(): 设置线程名。

使用 threading 模块创建线程

我们可以通过直接从 threading.Thread 继承创建一个新的子类,并实例化后调用 start() 方法启动新线程,即它调用了线程的 run() 方法:

实例

#!/usr/bin/python3

import threading

import time

exitFlag = 0

class myThread (threading.Thread):

def __init__(self, threadID, name, counter):

threading.Thread.__init__(self)

self.threadID = threadID

self.name = name

self.counter = counter

def run(self):

print ("开始线程:" + self.name)

print_time(self.name, self.counter, 5)

print ("退出线程:" + self.name)

def print_time(threadName, delay, counter):

while counter:

if exitFlag:

threadName.exit()

time.sleep(delay)

print ("%s: %s" % (threadName, time.ctime(time.time())))

counter -= 1

# 创建新线程

thread1 = myThread(1, "Thread-1", 1)

thread2 = myThread(2, "Thread-2", 2)

# 开启新线程

thread1.start()

thread2.start()

thread1.join()

thread2.join()

print ("退出主线程")

以上程序执行结果如下;

开始线程:Thread-1

开始线程:Thread-2

Thread-1: Wed Apr 6 11:46:46 2016

Thread-1: Wed Apr 6 11:46:47 2016

Thread-2: Wed Apr 6 11:46:47 2016

Thread-1: Wed Apr 6 11:46:48 2016

Thread-1: Wed Apr 6 11:46:49 2016

Thread-2: Wed Apr 6 11:46:49 2016

Thread-1: Wed Apr 6 11:46:50 2016

退出线程:Thread-1

Thread-2: Wed Apr 6 11:46:51 2016

Thread-2: Wed Apr 6 11:46:53 2016

Thread-2: Wed Apr 6 11:46:55 2016

退出线程:Thread-2

退出主线程

线程同步

如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。

使用 Thread 对象的 Lock 和 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间。如下:

多线程的优势在于可以同时运行多个任务(至少感觉起来是这样)。但是当线程需要共享数据时,可能存在数据不同步的问题。

考虑这样一种情况:一个列表里所有元素都是0,线程"set"从后向前把所有元素改成1,而线程"print"负责从前往后读取列表并打印。

那么,可能线程"set"开始改的时候,线程"print"便来打印列表了,输出就成了一半0一半1,这就是数据的不同步。为了避免这种情况,引入了锁的概念。

锁有两种状态——锁定和未锁定。每当一个线程比如"set"要访问共享数据时,必须先获得锁定;如果已经有别的线程比如"print"获得锁定了,那么就让线程"set"暂停,也就是同步阻塞;等到线程"print"访问完毕,释放锁以后,再让线程"set"继续。

经过这样的处理,打印列表时要么全部输出0,要么全部输出1,不会再出现一半0一半1的尴尬场面。

实例

#!/usr/bin/python3

import threading

import time

class myThread (threading.Thread):

def __init__(self, threadID, name, counter):

threading.Thread.__init__(self)

self.threadID = threadID

self.name = name

self.counter = counter

def run(self):

print ("开启线程: " + self.name)

# 获取锁,用于线程同步

threadLock.acquire()

print_time(self.name, self.counter, 3)

# 释放锁,开启下一个线程

threadLock.release()

def print_time(threadName, delay, counter):

while counter:

time.sleep(delay)

print ("%s: %s" % (threadName, time.ctime(time.time())))

counter -= 1

threadLock = threading.Lock()

threads = []

# 创建新线程

thread1 = myThread(1, "Thread-1", 1)

thread2 = myThread(2, "Thread-2", 2)

# 开启新线程

thread1.start()

thread2.start()

# 添加线程到线程列表

threads.append(thread1)

threads.append(thread2)

# 等待所有线程完成

for t in threads:

t.join()

print ("退出主线程")

执行以上程序,输出结果为:

开启线程: Thread-1

开启线程: Thread-2

Thread-1: Wed Apr 6 11:52:57 2016

Thread-1: Wed Apr 6 11:52:58 2016

Thread-1: Wed Apr 6 11:52:59 2016

Thread-2: Wed Apr 6 11:53:01 2016

Thread-2: Wed Apr 6 11:53:03 2016

Thread-2: Wed Apr 6 11:53:05 2016

退出主线程

线程优先级队列( Queue)

Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列 PriorityQueue。

这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。

Queue 模块中的常用方法:

Queue.qsize() 返回队列的大小

Queue.empty() 如果队列为空,返回True,反之False

Queue.full() 如果队列满了,返回True,反之False

Queue.full 与 maxsize 大小对应

Queue.get([block[, timeout]])获取队列,timeout等待时间

Queue.get_nowait() 相当Queue.get(False)

Queue.put(item) 写入队列,timeout等待时间

Queue.put_nowait(item) 相当Queue.put(item, False)

Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号

Queue.join() 实际上意味着等到队列为空,再执行别的操作

实例

#!/usr/bin/python3

import queue

import threading

import time

exitFlag = 0

class myThread (threading.Thread):

def __init__(self, threadID, name, q):

threading.Thread.__init__(self)

self.threadID = threadID

self.name = name

self.q = q

def run(self):

print ("开启线程:" + self.name)

process_data(self.name, self.q)

print ("退出线程:" + self.name)

def process_data(threadName, q):

while not exitFlag:

queueLock.acquire()

if not workQueue.empty():

data = q.get()

queueLock.release()

print ("%s processing %s" % (threadName, data))

else:

queueLock.release()

time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-3"]

nameList = ["One", "Two", "Three", "Four", "Five"]

queueLock = threading.Lock()

workQueue = queue.Queue(10)

threads = []

threadID = 1

# 创建新线程

for tName in threadList:

thread = myThread(threadID, tName, workQueue)

thread.start()

threads.append(thread)

threadID += 1

# 填充队列

queueLock.acquire()

for word in nameList:

workQueue.put(word)

queueLock.release()

# 等待队列清空

while not workQueue.empty():

pass

# 通知线程是时候退出

exitFlag = 1

# 等待所有线程完成

for t in threads:

t.join()

print ("退出主线程")

以上程序执行结果:

开启线程:Thread-1

开启线程:Thread-2

开启线程:Thread-3

Thread-3 processing One

Thread-1 processing Two

Thread-2 processing Three

Thread-3 processing Four

Thread-1 processing Five

退出线程:Thread-3

退出线程:Thread-2

退出线程:Thread-1

退出主线程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/news/329613.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

采用MiniProfiler监控EF与.NET MVC项目

今天来说说EF与MVC项目的性能检测和监控&#xff0c;相对本篇文章&#xff0c;更推荐大家使用另一个类似组件 NanoProfiler - 适合生产环境的性能监控类库 之 基本功能篇 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC MiniProfiler是Stack Ove…

(转)公钥,私钥和数字签名这样最好理解

转自&#xff1a; 公钥&#xff0c;私钥和数字签名这样最好理解_21aspnet的博客-CSDN博客_公钥签名还是私钥签名一、公钥加密 假设一下&#xff0c;我找了两个数字&#xff0c;一个是1&#xff0c;一个是2。我喜欢2这个数字&#xff0c;就保留起来&#xff0c;不告诉你们(私钥…

JavaWeb的web.xml标签元素(二)

JavaWeb的web.xml标签元素&#xff08;一&#xff09; 九、session-config为Web应用中的javax.servlet.http.HttpSession对象定义参数 session-config-session-timeout?session-timeout元素用来指定默认的会话超时时间间隔&#xff0c;以分钟为单位。该元素值必须为整数。如果…

登录系统 提示框_实物资产管理软件操作手册(职员和系统用户)

一、职员和系统用户“职员和系统用户”菜单提供了对公司人员信息进行维护的功能&#xff0c;可以自定义职员编码、 姓名、用户名等相关职员信息。注意&#xff1a;职员编码、用户名需唯一&#xff0c;且用户名一旦保存则不可修改。根据要求可以将“用户类型”分为“职员”和“系…

HoloLens开发手记-凝视 Gaze

凝视 Gaze 在全息应用中&#xff0c;凝视是第一种输入形式&#xff0c;被用于定位物体&#xff08;功能和PC的光标指针类似&#xff09;。凝视告诉你用户正在看向世界中的位置&#xff0c;让你能够确定他们的意图。在现实世界中&#xff0c;你通常会盯着你打算与之交互的物体。…

摘要算法与加密(以MD5算法为例)

【README】 部分内容总结自&#xff1a; 摘要与加密的区别&#xff08;以MD5算法为例&#xff09; - 掘金https://juejin.cn/post/6844903561478799368 【1】摘要算法与加密区别 【1.1】摘要算法&#xff08;不可逆&#xff09; 1&#xff09;摘要算法&#xff1a; 说白了…

Oracle入门(三A)之sqlplus

转载自 sqlplus /nolog是什么意思sqlplus命令格式如下&#xff1a; 用法: SQLPLUS [ [<option>] [<logon>] [<start>] ] 其中 <option> :: -H | -V | [ [-M <o>] [-R <n>] [-S] ] <登录> :: <用户名>[/<口令>][<con…

.Net Core下如何管理配置文件

一、前言 根据该issues来看&#xff0c;System.Configuration在.net core中已经不存在了&#xff0c;那么取而代之的是由Microsoft.Extensions.Cnfiguration.XXX一系列的类库提供&#xff0c;对应的开源地址为点击这里。 从当前开源的代码来看&#xff0c;在.net core下提供了…

python短视频自动制作_Python 带你一键生成朋友圈超火的九宫格短视频

1. 场景如果你经常刷抖音和微信朋友圈&#xff0c;一定发现了最近九宫格短视频很火&#xff01;​从朋友圈九宫格图片&#xff0c;到九宫格视频&#xff0c;相比传统的图片视频&#xff0c;前者似乎更有个性和逼格除了传统的剪辑软件可以实现&#xff0c;是否有其他更加快捷方便…

3-系统总线

【README】 1.本文总结自B站 《计算机组成原理&#xff08;哈工大刘宏伟&#xff09;》的视频讲解&#xff0c;非常棒&#xff0c;墙裂推荐&#xff1b; 2.补充&#xff1a;冯洛伊曼计算机由5大部分组成&#xff1a; 1. 运算器2. 控制器3. 存储器4. 输入设备5. …

HashMap中傻傻分不清楚的那些概念

转载自 HashMap中傻傻分不清楚的那些概念 很多人在通过阅读源码的方式学习Java&#xff0c;这是个很好的方式。而JDK的源码自然是首选。在JDK的众多类中&#xff0c;我觉得HashMap及其相关的类是设计的比较好的。很多人读过HashMap的代码&#xff0c;不知道你们有没有和我一样&…

HoloLens开发手记-硬件细节 Hardware Detail

微软HoloLens是世界第一款完全无线缆的全息计算机。通过在新方式上赋予用户的全息体验&#xff0c;HoloLens重新定义了个人计算&#xff08;Personal Computing&#xff09;。为了将3D全息图形固定到你周围的真实世界中&#xff0c;HoloLens融合了最先进的光学元件和传感器。 设…

super构造方法为什么给子类赋值_【Java学习 | Javase】super

整理自&#xff1a;动力节点基础讲义super概述 严格来说&#xff0c;super其实并不是一个引用&#xff0c;它只是一个关键字&#xff0c;super代表了当前对象中从父类继承过来的那部分特征。换句话说&#xff0c;super其实是this的一部分&#xff0c;从父类继承过来的属性和方法…

4-存储器

【README】 1.本文总结自B站 《计算机组成原理&#xff08;哈工大刘宏伟&#xff09;》的视频讲解&#xff0c;非常棒&#xff0c;墙裂推荐&#xff1b; 【1】概述 【1.1】存储器分类 1&#xff09;按存储介质分类 1&#xff0c; 半导体存储器&#xff0c;分为 TTL&#…

坑爹的日志无法按天切割问题

转载自 坑爹的日志无法按天切割问题问题背景 线上某个新管理型系统出现了日志无法按天切割生成日志文件的问题&#xff0c;所有的日志都在一个日志文件里面&#xff0c;只有每次重启的时候才会重新生成文件。 这个管理系统使用的是 Spring Boot Logback 框架&#xff0c;查看了…

Asp.net 面向接口框架之应用程序上下文作用域组件

在团队中推广面向接口开发两年左右,成果总体来说我还是挺满意的,使用面向接口开发的模块使用Unity容器配置的功能非常稳定,便于共享迁移(另一个项目使用只需要复制配置和调用接口即可)也很好扩展(操作的数据库、表、资源等都可以配置)。 但是由于当时开发的匆忙(边开发边应用),…

投票源码程序_[内附完整源码和文档] 基于JSP实现的影视创作论坛系统

摘 要随着时代的发展&#xff0c;互联网的出现&#xff0c;给传统影视行业带来的最大便利就是&#xff0c;方便了影视从业人员以及爱好者的交流和互动&#xff0c;而为用户提供一个书写影评&#xff0c;阅读影评以及回复影评的平台&#xff0c;以影评为载体来使用户感受影评、解…

5-输入输出系统IO

【README】 1.本文总结自B站 《计算机组成原理&#xff08;哈工大刘宏伟&#xff09;》的视频讲解&#xff0c;非常棒&#xff0c;墙裂推荐&#xff1b; 【1】 IO概述 【1.1】输入输出系统的发展概况 通道&#xff08;通道是netty的io多路复用的底层原理&#xff0c;需要重点了…

Java中的基本数据类型转换(自动、强制、提升)

转载自 Java中的基本数据类型转换&#xff08;自动、强制、提升&#xff09; 说基本数据类型转换之前&#xff0c;先了解下 Java 中的 8 种基本数据类型&#xff0c;以及它们的占内存的容量大小和表示的范围&#xff0c;如下图所示。 重新温故了下原始数据类型&#xff0c;现在…

我是这样入侵 Hacking Team 的

在意大利间谍软件厂商 Hacking Team 的内部邮件和文档被曝光将近一年后&#xff0c;黑掉这家黑客公司的黑客公开了他如何入侵HT的完整细节。该文档于上周六在网上发布&#xff0c;本意是为了给黑客活动人士的一份指南。但对于安全从业人员来说&#xff0c;则意味着当任何企业或…