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