5.线程实现

本文介绍了Python中的线程实现,包括_thread模块和threading模块的区别及使用方法。详细讲解了threading模块提供的高级功能,如线程的状态管理和面向对象的线程实现。

用于线程实现的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的函数。 线程在函数返回时终止。

import _thread
import time
def print_time(threadName, delay):
    count = 0
    while count < 5:
        time.sleep(delay)
        count += 1
        print("{}: {}".format(threadName, time.ctime(time.time())))

try:
    _thread.start_new_thread(print_time, ("thread_1", 2))
    _thread.start_new_thread(print_time, ("thread_2", 3))
except Exception as e:
    print(e)
while 1:
    pass

运行结果:

E:\Anaconda\python.exe F:/PythonSpace/Concurrent/1.function_thread.py
thread_1: Sat Mar 23 15:29:21 2019
thread_2: Sat Mar 23 15:29:22 2019
thread_1: Sat Mar 23 15:29:23 2019
thread_2: Sat Mar 23 15:29:25 2019
thread_1: Sat Mar 23 15:29:25 2019
thread_1: Sat Mar 23 15:29:27 2019
thread_2: Sat Mar 23 15:29:28 2019
thread_1: Sat Mar 23 15:29:29 2019
thread_2: Sat Mar 23 15:29:31 2019
thread_2: Sat Mar 23 15:29:34 2019

threading模块

threading模块以面向对象的方式实现,并将每个线程视为一个对象。 因此,它为线程提供了比_thread模块更强大。

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

  • threading.activeCount() - 此方法返回处于活动状态的线程对象的数量
  • threading.currentThread() - 此方法返回调用者线程控制中的线程对象数。
  • threading.enumerate() - 此方法返回当前活动的所有线程对象的列表。

为了实现线程,threading模块具有提供以下方法的Thread类 -

  • run() - run()方法是线程的入口点。
  • start() - start()方法通过调用run方法来启动线程。
  • join([time]) - join()等待线程终止。
  • isAlive() - isAlive()方法检查线程是否仍在执行。
  • getName() - getName()方法返回线程的名称。
  • setName() - setName()方法设置线程的名称。

如何使用threading模块创建线程。 按照以下步骤使用threading模块创建一个新线程 :

  • 第1步 - 在这一步中,需要定义Thread类的新子类。
  • 第2步 - 然后为了添加额外的参数,需要重写__init __(self [,args])方法。
  • 第3步 - 在这一步中,需要重写run(self [,args])方法来实现线程在启动时应该执行的操作。

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

import threading
import time

class MyThread(threading.Thread):
    def __init__(self, thread_id, thread_name, delay):
        threading.Thread.__init__(self)
        self.thread_id = thread_id
        self.thread_name = thread_name
        self.delay = delay

    def run(self):
       # 重写run()
        print_time(self.thread_name, self.delay, 5)

def print_time(thread_name, delay, counter):
    while counter:
        time.sleep(delay)
        print("{}: {}".format(thread_name, 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")

运行结果:

E:\Anaconda\python.exe F:/PythonSpace/Concurrent/2.object_threading.py
Exiting Main Thread
thread-1: Sat Mar 23 16:10:14 2019
thread-2: Sat Mar 23 16:10:15 2019
thread-1: Sat Mar 23 16:10:15 2019
thread-1: Sat Mar 23 16:10:16 2019
thread-2: Sat Mar 23 16:10:17 2019
thread-1: Sat Mar 23 16:10:17 2019
thread-1: Sat Mar 23 16:10:18 2019
thread-2: Sat Mar 23 16:10:19 2019
thread-2: Sat Mar 23 16:10:21 2019
thread-2: Sat Mar 23 16:10:23 2019

带有线程状态的Python程序

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

下面的Python程序在start()sleep()join()方法的帮助下将分别显示线程是如何进入运行,等待和死亡状态的。

第1步 - 导入必要的模块,threadingtime

import threading
import 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中,可以通过不同的方式启动一个新的线程,但其中最简单的一个就是将其定义为一个单一的函数。 在定义函数之后,可以将它作为新线程的目标。线程对象等等。

import threading
import time
import random

def Thread_exec(i):
    print("Execution of Thread {} started\n".format(i))
    sleepTime = random.randint(1, 4)
    time.sleep(sleepTime)
    print("Execution of Thread {} finished\n".format(i))

for i in range(4):
    thread = threading.Thread(target=Thread_exec, args=(i,))
    thread.start()
    print("Active Threads:{}".format(threading.enumerate()))

运行结果:

E:\Anaconda\python.exe F:/PythonSpace/Concurrent/4.function_threading.py
Execution of Thread 0 started
Active Threads:[<_MainThread(MainThread, started 4036)>, <Thread(Thread-1, started 13244)>]

Execution of Thread 1 started
Active Threads:[<_MainThread(MainThread, started 4036)>, <Thread(Thread-1, started 13244)>, <Thread(Thread-2, started 13468)>]

Execution of Thread 2 started
Active Threads:[<_MainThread(MainThread, started 4036)>, <Thread(Thread-1, started 13244)>, <Thread(Thread-2, started 13468)>, <Thread(Thread-3, started 6300)>]

Execution of Thread 3 started
Active Threads:[<_MainThread(MainThread, started 4036)>, <Thread(Thread-1, started 13244)>, <Thread(Thread-2, started 13468)>, <Thread(Thread-3, started 6300)>, <Thread(Thread-4, started 13860)>]

Execution of Thread 3 finished

Execution of Thread 0 finished

Execution of Thread 2 finished
Execution of Thread 1 finished

 

转载于:https://my.oschina.net/gain/blog/3026845

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值