Python多线程

Python线程实现

Python线程实现详细操作教程
在本章中,我们将学习如何在Python中实现线程。

用于线程实现的Python模块

Python线程有时称为轻量级进程,因为线程比进程占用更少的内存。线程允许一次执行多个任务。在Python中,我们有以下两个模块在程序中实现线程-
<_ thread> 模块 模块
这两个模块之间的主要区别是 <_ thread> 模块将线程视为函数,而 模块将每个线程视为对象,而以面向对象的方式实现它。而且, <_ thread> 模块在低级线程中有效,并且功能少于 模块。

<_ thread>模块

在早期的Python版本中,我们拥有 模块,但是很长一段时间以来,它都被认为是"不推荐使用"的模块。鼓励用户改用 模块。因此,在Python 3中,模块"线程"不再可用。由于Python3中的向后不兼容,它已重命名为" <_ thread> "。
要在 <_ thread> 模块的帮助下生成新线程,我们需要调用它的 start_new_thread 方法。可以在以下语法的帮助下了解此方法的工作方式-
_thread.start_new_thread ( function, args[, kwargs] )
这里-
args 是参数的元组 kwargs 是关键字参数的可选词典
如果要在不传递参数的情况下调用函数,则需要在 args 中使用一个空的参数元组。
此方法调用立即返回,子线程启动,并使用传递的args列表(如果有)调用函数。该线程在函数返回时终止。

示例

以下是使用 <_ thread> 模块生成新线程的示例。我们在这里使用start_new_thread()方法。
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
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: unable to start thread")
while 1:
   pass

输出

以下输出将借助于 <_ thread> 模块帮助我们了解新线程的生成。
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
Thread-1: Mon Apr 23 10:03:33 2018
Thread-2: Mon Apr 23 10:03:35 2018
Thread-1: Mon Apr 23 10:03:35 2018
Thread-1: Mon Apr 23 10:03:37 2018
Thread-2: Mon Apr 23 10:03:39 2018
Thread-1: Mon Apr 23 10:03:39 2018
Thread-1: Mon Apr 23 10:03:41 2018
Thread-2: Mon Apr 23 10:03:43 2018
Thread-2: Mon Apr 23 10:03:47 2018
Thread-2: Mon Apr 23 10:03:51 2018

模块

模块以面向对象的方式实现,并将每个线程都视为一个对象。因此,与<_thread>模块相比,它为线程提供了更强大的高层支持。该模块包含在Python 2.4中。

模块中的其他方法

模块包含 <_ thread> 模块的所有方法,但它还提供了其他方法。其他方法如下-
threading.activeCount()-此方法返回活动线程对象的数量 threading.currentThread()-此方法返回调用者线程控件中线程对象的数量。 threading.enumerate()-此方法返回当前处于活动状态的所有线程对象的列表。
对于实现线程, 模块具有 Thread 类,该类提供以下方法-
run()-run()方法是线程的入口点。 start()-start()方法通过调用run方法来启动线程。 join([time])-join()等待线程终止。 isAlive()-isAlive()方法检查线程是否仍在执行。 getName()-getName()方法返回线程的名称。 setName()-setName()方法设置线程的名称。

如何使用模块创建线程?

在本节中,我们将学习如何使用 模块创建线程。请按照以下步骤使用 模块创建新线程-
步骤1 -在这一步中,我们需要定义 Thread 类的新子类。 步骤2 -然后,要添加其他参数,我们需要覆盖 __ init __(self [,args])方法。 步骤3 -在这一步中,我们需要重写run(self [,args])方法以实现线程在启动时应执行的操作。
现在,在创建新的 Thread 子类之后,我们可以创建它的实例,然后通过调用 start()来启动新线程,然后依次调用 run()方法。

示例

请考虑以下示例,以学习如何使用 模块生成新线程。
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
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 ("Starting " + self.name)
      print_time(self.name, self.counter, 5)
      print ("Exiting " + 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 ("Exiting Main Thread")
Starting Thread-1
Starting Thread-2

输出

现在,考虑以下输出-
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
Thread-1: Mon Apr 23 10:52:09 2018
Thread-1: Mon Apr 23 10:52:10 2018
Thread-2: Mon Apr 23 10:52:10 2018
Thread-1: Mon Apr 23 10:52:11 2018
Thread-1: Mon Apr 23 10:52:12 2018
Thread-2: Mon Apr 23 10:52:12 2018
Thread-1: Mon Apr 23 10:52:13 2018
Exiting Thread-1
Thread-2: Mon Apr 23 10:52:14 2018
Thread-2: Mon Apr 23 10:52:16 2018
Thread-2: Mon Apr 23 10:52:18 2018
Exiting Thread-2
Exiting Main Thread

适用于各种线程状态的Python程序

有五个线程状态-新的,可运行的,正在运行的,等待的和死的。在这五个状态中,我们将主要关注三个状态-运行,等待和死亡。线程在运行状态下获取其资源,在等待状态下等待资源;资源的最终释放(如果正在执行和获取)处于无效状态。
下面的Python程序借助start(),sleep()和join()方法将显示线程如何分别进入运行,等待和死机状态。
步骤1 -导入必要的模块
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
import threading
import time
步骤2 -定义一个函数,该函数将在创建线程时调用。
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
def thread_states():
   print("Thread entered in running state")
步骤3 -我们正在使用时间模块的sleep()方法,使我们的线程等待说2秒钟。
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
time.sleep(2)
第4步-现在,我们创建一个名为T1的线程,该线程采用上面定义的函数的参数。
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
T1 = threading.Thread(target=thread_states)
第5步-现在,借助start()函数,我们可以启动线程。它将生成消息,该消息是我们在定义函数时设置的。
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
T1.start()
Thread entered in running state
步骤6 -现在,最后,我们可以在完成执行后使用join()方法终止线程。
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
T1.join()

在Python中启动线程

在python中,我们可以通过不同的方式启动新线程,但其中最简单的方法是将其定义为单个函数。定义函数后,我们可以将其作为新的 threading.Thread 对象的目标,等等。执行以下Python代码以了解该功能的工作原理-
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
import threading
import time
import random
def Thread_execution(i):
   print("Execution of Thread {} started\n".format(i))
   sleepTime = random.randint(1,4)
   time.sleep(sleepTime)
   print("Execution of Thread {} finished".format(i))
for i in range(4):
   thread = threading.Thread(target=Thread_execution, args=(i,))
   thread.start()
   print("Active Threads:" , threading.enumerate())

输出

# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
Execution of Thread 0 started
Active Threads:
   [<_MainThread(MainThread, started 6040)>,
      <HistorySavingThread(IPythonHistorySavingThread, started 5968)>,
      <Thread(Thread-3576, started 3932)>]
Execution of Thread 1 started
Active Threads:
   [<_MainThread(MainThread, started 6040)>,
      <HistorySavingThread(IPythonHistorySavingThread, started 5968)>,
      <Thread(Thread-3576, started 3932)>,
      <Thread(Thread-3577, started 3080)>]
Execution of Thread 2 started
Active Threads:
   [<_MainThread(MainThread, started 6040)>,
      <HistorySavingThread(IPythonHistorySavingThread, started 5968)>,
      <Thread(Thread-3576, started 3932)>,
      <Thread(Thread-3577, started 3080)>,
      <Thread(Thread-3578, started 2268)>]
Execution of Thread 3 started
Active Threads:
   [<_MainThread(MainThread, started 6040)>,
      <HistorySavingThread(IPythonHistorySavingThread, started 5968)>,
      <Thread(Thread-3576, started 3932)>,
      <Thread(Thread-3577, started 3080)>,
      <Thread(Thread-3578, started 2268)>,
      <Thread(Thread-3579, started 4520)>]
Execution of Thread 0 finished
Execution of Thread 1 finished
Execution of Thread 2 finished
Execution of Thread 3 finished

Python中的守护程序线程

在Python中实现守护程序线程之前,我们需要了解守护程序线程及其用法。在计算方面,守护程序是一个后台进程,用于处理对各种服务的请求,例如数据发送,文件传输等。如果不再需要它,它将处于休眠状态。借助非守护程序线程也可以完成相同的任务。但是,在这种情况下,主线程必须手动跟踪非守护程序线程。另一方面,如果我们使用守护程序线程,则主线程可以完全忘记这一点,并且在主线程退出时将被杀死。关于守护程序线程的另一个重要点是,我们可以选择仅将它们用于非必要的任务,如果它们没有完成或在两次任务之间被杀死,这些任务不会对我们造成影响。以下是python中守护程序线程的实现-
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
import threading
import time
def nondaemonThread():
   print("starting my thread")
   time.sleep(8)
   print("ending my thread")
def daemonThread():
   while True:
   print("Hello")
   time.sleep(2)
if __name__ == '__main__':
   nondaemonThread = threading.Thread(target = nondaemonThread)
   daemonThread = threading.Thread(target = daemonThread)
   daemonThread.setDaemon(True)
   daemonThread.start()
   nondaemonThread.start()
在上面的代码中,有两个函数,分别是 > nondaemonThread()> daemonThread()。第一个函数打印其状态并在8秒钟后进入休眠状态,而deamonThread()函数每2秒钟无限期地打印一次Hello。通过以下输出,我们可以了解nondaemon和daemon线程之间的区别-
# Filename : example.py
# Copyright : 2020 By Lidihuo
# Author by : www.lidihuo.com
# Date : 2020-08-22
Hello
starting my thread
Hello
Hello
Hello
Hello
ending my thread
Hello
Hello
Hello
Hello
Hello
昵称: 邮箱:
Copyright © 2022 立地货 All Rights Reserved.
备案号:京ICP备14037608号-4