开发手册 欢迎您!
软件开发者资料库

线程的实现

Python中的并发性线程的实现 - 从简单而简单的步骤学习Python中的并发性,从基本概念到高级概念,包括简介,并发与并行,系统和内存架构,线程,线程实现,同步线程,线程互通,测试,调试线程应用程序,基准测试和分析,线程池,进程池,多处理,进程交互,事件驱动,反应式编程。

在本章中,我们将学习如何在Python中实现线程.

用于线程实现的Python模块

Python线程有时称为轻量级进程因为线程占用的内存比进程少得多.线程允许一次执行多个任务.在Python中,我们有以下两个模块在程序中实现线程 :

  • < _thread> 模块

  • < threading> 模块

这两个模块之间的主要区别在于< _thread> 模块将线程视为一个函数,而< threading> 模块将每个线程视为一个对象,并以面向对象的方式实现它.此外,< _thread> 模块在低级线程中有效,并且具有比< threading> 模块更少的功能.

< _Thread>模块

在Python的早期版本中,我们有< thread> 模块,但在相当长的时间内它被认为是"已弃用".我们鼓励用户使用< threading> 模块.因此,在Python 3中,模块"thread"不再可用.它已被重命名为"< _thread> ",以解决Python3中的向后不兼容问题.

< _thread>的帮助下生成新线程; 模块,我们需要调用它的 start_new_thread 方法.可以通过以下语法 : 来理解此方法的工作;

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

这里 : 去;

  • args 是一个参数元组

  • kwargs 是关键字参数的可选字典

如果我们想在不传递参数的情况下调用函数,那么我们需要在 args 中使用一个空元组参数.

此方法调用立即返回,子线程启动,并使用传递的args列表(如果有)调用函数.线程在函数返回时终止.

示例

以下是使用< _thread>生成新线程的示例; 模块.我们在这里使用start_new_thread()方法.

import _threadimport timedef 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> 模块的帮助下理解新线程的生成.

Thread-1: Mon Apr 23 10:03:33 2018Thread-2: Mon Apr 23 10:03:35 2018Thread-1: Mon Apr 23 10:03:35 2018Thread-1: Mon Apr 23 10:03:37 2018Thread-2: Mon Apr 23 10:03:39 2018Thread-1: Mon Apr 23 10:03:39 2018Thread-1: Mon Apr 23 10:03:41 2018Thread-2: Mon Apr 23 10:03:43 2018Thread-2: Mon Apr 23 10:03:47 2018Thread-2: Mon Apr 23 10:03:51 2018

模块

< threading> 模块以面向对象的方式实现,并将每个线程视为一个对象.因此,它为线程提供了比

< threading>中的其他方法.模块

< threading> 模块包含< _thread> 模块的所有方法,但它也提供了其他方法.其他方法如下 :

  • threading.activeCount() : 此方法返回活动的线程对象的数量

  • threading.currentThread() : 此方法返回调用者线程控件中的线程对象数.

  • threading.enumerate() : 此方法返回当前活动的所有线程对象的列表.

  • 为了实现线程,< threading> 模块具有 线程 类提供以下方法 :

    • run() :  run()方法是线程的入口点.

    • start() :  start()方法通过调用run方法启动一个线程.

    • join([time]) :  join()等待线程终止.

    • isAlive() :  isAlive()方法检查线程是否仍在执行.

    • getName() :  getName()方法返回一个线程的名称.

    • setName() :  setName()方法设置线程的名称.

如何使用< threading>创建线程模块?

在本节中,我们将学习如何使用< threading> 模块创建线程.按照以下步骤使用< threading>创建新线程module :

  • 第1步 : 在这一步中,我们需要定义 Thread 类的新子类.

  • 第2步  : 去;然后,为了添加其他参数,我们需要覆盖 __ init __(self [,args])方法.

  • 步骤3 : 在这一步中,我们需要覆盖run(self [,args])方法来实现线程在启动时应该做的事情.

  • 现在,在创建新的 Thread 子类,我们可以创建它的一个实例,然后通过调用 start()启动一个新线程,然后调用 run()方法.

示例

考虑此示例以了解如何使用

import threadingimport timeexitFlag = 0class 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 -= 1thread1 = 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-1Starting Thread-2

输出

现在,考虑以下输出 :

Thread-1: Mon Apr 23 10:52:09 2018Thread-1: Mon Apr 23 10:52:10 2018Thread-2: Mon Apr 23 10:52:10 2018Thread-1: Mon Apr 23 10:52:11 2018Thread-1: Mon Apr 23 10:52:12 2018Thread-2: Mon Apr 23 10:52:12 2018Thread-1: Mon Apr 23 10:52:13 2018Exiting Thread-1Thread-2: Mon Apr 23 10:52:14 2018Thread-2: Mon Apr 23 10:52:16 2018Thread-2: Mon Apr 23 10:52:18 2018Exiting Thread-2Exiting Main Thread

各种Python程序线程状态

有五种线程状态 - 新的,可运行的,正在运行的,等待的和死的.在这五个中,我们主要关注三个州 - 跑步,等待和死亡.线程将其资源置于运行状态,等待处于等待状态的资源;资源的最终版本,如果执行和获取处于死状态.

以下Python程序将在start(),sleep()和join()方法的帮助下显示线程如何分别进入跑步,等待和死亡状态.

步骤1 : 导入必要的模块,< threading>和< time>

import threadingimport time

第2步 : 定义一个函数,在创建线程时调用该函数.

def thread_states():   print("Thread entered in running state")

第3步 : 我们使用time模块的sleep()方法让我们的线程等待2秒钟.

  time.sleep(2)

第4步 : 现在,我们创建一个名为T1的线程,它接受上面定义的函数的参数.

  T1 = threading.Thread(target = thread_states )

第5步 : 现在,在start()函数的帮助下,我们可以启动我们的线程.它将生成消息,该消息由我们在定义函数时设置.

T1.start()Thread entered in running state

步骤6 : 现在,最后我们可以在完成执行后使用join()方法终止该线程.

  T1.join()

在Python中启动线程

在python中,我们可以通过不同方式启动一个新线程,但其中最简单的一个是将其定义为单个函数.在定义函数之后,我们可以将其作为新 threading.Thread 对象的目标传递,依此类推.执行以下Python代码以了解函数的工作原理和减号;

import threadingimport timeimport randomdef 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())

输出

Execution of Thread 0 startedActive Threads:   [<_MainThread(MainThread, started 6040)>,      ,      ]Execution of Thread 1 startedActive Threads:   [<_MainThread(MainThread, started 6040)>,      ,      ,      ]Execution of Thread 2 startedActive Threads:   [<_MainThread(MainThread, started 6040)>,      ,      ,      ,      ]Execution of Thread 3 startedActive Threads:   [<_MainThread(MainThread, started 6040)>,      ,      ,      ,      ,      ]Execution of Thread 0 finishedExecution of Thread 1 finishedExecution of Thread 2 finishedExecution of Thread 3 finished

Python中的守护程序线程

在Python中实现守护程序线程之前,我们需要了解守护程序线程及其用法.在计算方面,守护进程是一个后台进程,它处理各种服务的请求,例如数据发送,文件传输等.如果不再需要它,它将处于休眠状态.同样的任务也可以在非守护程序线程的帮助下完成.但是,在这种情况下,主线程必须手动跟踪非守护程序线程.另一方面,如果我们使用守护程序线程,那么主线程可以完全忘记这一点,它将在主线程退出时被终止.关于守护程序线程的另一个要点是,我们可以选择仅将它们用于非必要任务,如果它们没有完成或在它们之间被杀死则不会影响我们.以下是python中的守护程序线程的实现 :

import threadingimport timedef 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和守护程序线程之间的区别;

Hellostarting my threadHelloHelloHelloHelloending my threadHelloHelloHelloHelloHello