共计 4673 个字符,预计需要花费 12 分钟才能阅读完成。
在这个 Python 多线程教程中,您将看到创立线程的不同办法,并学习实现线程平安操作的同步。这篇文章的每个局部都蕴含一个示例和示例代码,以逐渐解释该概念。
顺便说一下,多线程是简直所有高级编程语言都反对的软件编程的外围概念。因而,您应该晓得的第一件事是:什么是线程以及多线程在计算机科学中意味着什么。
什么是计算机科学中的线程?
在软件编程中,线程是具备独立指令集的最小执行单元。它是过程的一部分,并在共享程序的可运行资源(如内存)的雷同上下文中运行。一个线程有一个终点、一个执行程序和一个后果。它有一个指令指针,用于保留线程的以后状态并管制接下来按什么程序执行。
什么是计算机科学中的多线程?
一个过程并行执行多个线程的能力称为多线程。现实状况下,多线程能够显着进步任何程序的性能。而且 Python 多线程机制十分人性化,您能够疾速学习。
多线程的长处
- 多线程能够显着进步多处理器或多核零碎的计算速度,因为每个处理器或核同时解决一个独自的线程。
- 多线程容许程序在一个线程期待输出时放弃响应,同时另一个线程运行 GUI。此陈说实用于多处理器或单处理器零碎。
- 过程的所有线程都能够拜访其全局变量。如果一个全局变量在一个线程中发生变化,那么它对其余线程也是可见的。线程也能够有本人的局部变量。
多线程的毛病
- 在单处理器零碎上,多线程不会影响计算速度。因为治理线程的开销,性能可能会降落。
- 访问共享资源时须要同步以避免互斥。它间接导致更多的内存和 CPU 利用率。
- 多线程减少了程序的复杂性,从而也使得调试变得艰难。
- 它减少了潜在死锁的可能性。
- 当线程无奈定期访问共享资源时,它可能会导致饥饿。应用程序将无奈复原其工作。
到目前为止,您曾经浏览了无关线程的实践概念。如果您不相熟 Python,咱们建议您浏览咱们的 30 个疾速 Python 编码技巧,它们也能够帮忙您编写 Python 多线程代码。咱们的许多读者都应用了这些技巧,并且可能进步他们的编码技能。
Python 多线程模块
Python 提供了两个模块来在程序中实现线程。
模块和
< 线程 > 模块。
留神:供您参考,Python 2.x 已经有 < thread> 模块。但它在 Python 3.x 中被弃用并重命名为 < _thread> 模块以实现向后兼容性。
两个模块的次要区别在于模块 <_线程 > 将线程实现为函数。另一方面,< threading > 模块提供了一种面向对象的办法来启用线程创立。
如何应用线程模块创立线程?
如果你决定在你的程序中利用 < thread > 模块,那么应用上面的办法来产生线程。
# 语法
thread.start_new_thread (function, args[, kwargs] )
这种办法对于创立线程十分无效和间接。您能够应用它在 Linux 和 Windows 中运行程序。
此办法启动一个新线程并返回其标识符。它将应用传递的参数列表调用指定为“函数”参数的函数。当 < function > 返回时,线程将静默退出。
这里,args 是一个参数元组;应用空元组调用 < function > 不带任何参数。可选的 < kwargs > 参数指定关键字参数的字典。
** 如果 < function > 因未解决的异样而终止,则会打印堆栈跟踪,而后线程退出(它不会影响其余线程,它们会持续运行)。应用以下代码理解无关线程的更多信息。
根本的 Python 多线程示例
#Python 多线程示例。#1. 应用递归计算阶乘。#2. 应用线程调用阶乘函数。from _thread import start_new_thread
from time import sleep
threadId = 1 #线程计数器
waiting = 2 #2 秒期待的工夫
def factorial(n):
global threadId
rc = 0
if n < 1: # base case
print("{}: {}".format('\nThread', threadId))
threadId += 1
rc = 1
else:
returnNumber = n * factorial(n - 1) # recursive call
print("{} != {}".format(str(n), str(returnNumber)))
rc = returnNumber
return rc
start_new_thread(factorial, (5,))
start_new_thread(factorial, (4,))
print("Waiting for threads to return...")
sleep(waiting)
您能够在本地 Python 终端中运行上述代码,也能够应用任何在线 Python 终端。执行此程序后,它将产生以下输入。
程序输入
# Python 多线程:程序输入 -
期待线程返回...
Thread: 1
1 != 1
2 != 2
3 != 6
4 != 24
5 != 120
Thread: 2
1 != 1
2 != 2
3 != 6
4 != 24
如何应用线程模块创立线程?
最新的 < threading > 模块比上一节探讨的遗留 < thread > 模块提供了丰盛的个性和更好的线程反对。< threading > 模块是 Python 多线程的一个很好的例子。
< threading > 模块联合了 < thread > 模块的所有办法,并裸露了一些额定的办法
- threading.activeCount():它找到总数。流动线程对象。
- threading.currentThread():您能够应用它来确定调用方线程管制中的线程对象数量。
- threading.enumerate():它将为您提供以后流动的线程对象的残缺列表。
除了上述办法,< threading > 模块还提供了 < Thread > 类,你能够尝试实现线程。它是 Python 多线程的面向对象的变体。
应用线程模块实现线程的步骤
您能够依照以下步骤应用 < threading > 模块实现一个新线程。
- 从 < Thread > 类结构一个子类。
- 笼罩 < init(self [,args]) > 办法以依据要求提供参数。
- 接下来,重写 < run(self [,args]) > 办法来编写线程的业务逻辑。
一旦定义了新的 < Thread> 子类,就必须实例化它以启动一个新线程。而后,调用 < start()> 办法来启动它。它最终会调用 < run()> 办法来执行业务逻辑。
示例 – 创立一个线程类来打印日期
#Python 多线程示例打印以后日期。#1. 应用 threading.Thread 类定义子类。#2. 实例化子类并触发线程。import threading
import datetime
class myThread (threading.Thread):
def __init__(self, name, counter):
threading.Thread.__init__(self)
self.threadID = counter
self.name = name
self.counter = counter
def run(self):
print("\nStarting" + self.name)
print_date(self.name, self.counter)
print("Exiting" + self.name)
def print_date(threadName, counter):
datefields = []
today = datetime.date.today()
datefields.append(today)
print("{}[{}]: {}".format( threadName, counter, datefields[0] ))
# 创立新线程
thread1 = myThread("Thread", 1)
thread2 = myThread("Thread", 2)
# 启动新线程
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print("\nExiting the Program!!!")
程序输入
Starting Thread
Thread[1]: 2021-07-22
Exiting Thread
Starting Thread
Thread[2]: 2021-07-22
Exiting Thread
Exiting the Program!!!
Python 多线程——同步线程
< threading > 模块具备实现锁定的内置性能,容许您同步线程。须要锁定来管制对共享资源的拜访,以避免损坏或失落数据。
您能够调用 Lock() 办法来利用锁,它返回新的锁对象。而后,您能够调用锁对象的获取(阻塞)办法来强制线程同步运行。
可选的阻塞参数指定线程是否期待获取锁。
- Case Blocking = 0:如果获取锁失败,线程将立刻返回零值,如果锁胜利则返回一。
- Case Blocking = 1:线程阻塞并期待锁被开释。
锁对象的 release() 办法用于在不再须要时开释锁。
仅供参考,Python 的内置数据结构(例如列表、字典)是线程平安的,因为它具备用于操作它们的原子字节码的副作用。在 Python 中实现的其余数据结构或根本类型(如整数和浮点数)没有这种爱护。为了避免同时拜访一个对象,咱们应用了一个 Lock 对象。
锁定的多线程示例
#Python 多线程示例来演示锁定。#1. 应用 threading.Thread 类定义子类。#2. 实例化子类并触发线程。#3. 在线程的 run 办法中实现锁。import threading
import datetime
exitFlag = 0
class myThread (threading.Thread):
def __init__(self, name, counter):
threading.Thread.__init__(self)
self.threadID = counter
self.name = name
self.counter = counter
def run(self):
print("\nStarting" + self.name)
# 获取锁同步线程
threadLock.acquire()
print_date(self.name, self.counter)
# 为下一个线程开释锁
threadLock.release()
print("Exiting" + self.name)
def print_date(threadName, counter):
datefields = []
today = datetime.date.today()
datefields.append(today)
print("{}[{}]: {}".format( threadName, counter, datefields[0] ))
threadLock = threading.Lock()
threads = []
# 创立新线程
thread1 = myThread("Thread", 1)
thread2 = myThread("Thread", 2)
# 启动新线程
thread1.start()
thread2.start()
# 增加线程到线程列表
threads.append(thread1)
threads.append(thread2)
# 期待所有线程实现
for thread in threads:
thread.join()
print("\nExiting the Program!!!")
程序输入
Starting Thread
Thread[1]: 2021-07-22
Exiting Thread
Starting Thread
Thread[2]: 2021-07-22
Exiting Thread
Exiting the Program!!!