你所在的位置: 首页 > 正文

Python多线程编程(三十一)

2019-09-11 点击:905

同时运行多个线程类似于同时运行多个不同的程序,但具有以下好处 -

进程中的多个线程与主线程共享相同的数据空间,因此与单独的进程相比,共享信息或相互通信更容易。线程有时被称为轻量级进程,它们不需要太多内存开销;它们比流程便宜。

该线程具有启动,执行顺序和终止。它有一个指令指针,可以跟踪它在其上下文中当前运行的位置。

它可以被抢占(中断)。当其他线程正在运行时,它可以暂时保留(也称为睡眠) - 这称为让步。

有两种不同的线程 -

内核线程用户线程

内核线程是操作系统的一部分,并且内核中未实现用户空间线程。

在Python 3中有两个支持线程的模块 -

_threadthreading

线程模块已经“不推荐”了很长时间。建议用户使用线程模块。因此,在Python 3中,线程模块不再可用。但是,为了在Python 3中向后兼容,线程模块已重命名为“_thread”。

1.开始一个新线程

要生成/启动线程,需要在线程模块中调用以下方法 -

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

此方法调用可以在Linux和Windows中快速有效地创建新线程。

方法调用立即返回,并且子线程启动并使用传递的args列表调用该函数。函数返回时,线程终止。

这里,args是元组的参数;使用空元组调用函数意味着不传递任何参数。 Kwargs是关键字参数的可选字典。

实施例

#!/usr/bin/python 3

Import_thread

导入时间

#定义线程的函数

Def print_time(threadName,delay):

计数=0

计数< 5:

时间。睡觉(延迟)

计数+=1

打印('%s0x 1778%s'%)(threadName,time.CTime(time.time())

#创建两个线程,如下所示

试试:

_线程。 start_new_thread(print_time,('Thread-1',2,)

_线程。 start_new_thread(print_time,('Thread-2',4,)

除了:

打印('错误:无法启动线程')

而1:

执行上述代码时,会生成以下结果 -

F: worksp Python> Python thread_start.py

Thread-1: Tue Jun 2703: 06: 09 2018

Thread-2: Tue Jun 27 03: 06: 11 2018

Thread-1: Tue Jun 27 03: 06: 11 2018

Thread-1: Tue Jun 2703: 06: 13 2018

Thread-2: Tue Jun 27 03: 06: 15 2018

Thread-1: Tue Jun 2703: 06: 15 2018

程序进入无限循环,按ctrl-c可以停止或退出。虽然它对于低级线程非常有效,但与较新的线程模块相比,线程非常有限。

2.线程模块

Python 2.4中包含的较新的线程模块为线程提供了比上面讨论的线程模块更高级的支持。

线程模块公开了线程模块的所有方法,并提供了一些其他方法 -

threading.activeCount() - 返回活动线程对象的数量。 threading.currentThread() - 返回调用者线程控件中的线程对象数。 Threading.enumerate() - 返回当前活动的所有线程对象的列表。

除了这些方法之外,线程模块还有一个实现线程的Thread类。 Thread类提供的方法如下:

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

3.使用线程模块

创建线程

要使用线程模块实现新线程,必须执行以下操作:

定义Thread类的新子类。覆盖__init __(self [,args])方法以添加其他参数。然后,重写run(self [,args])方法以实现线程在启动时应该执行的操作。

一旦创建了Thread的新子类,就可以创建一个实例,然后调用start()方法调用run()方法来启动一个新线程。

实施例

#!的/usr/bin中/python3

导入线程

导入时间

exitFlag=0

类MyThread(threading.Thread):

Def __init __(self,threadID,name,counter):

threading.Thread .__初始化__(个体)

self.threadID=threadID

Self.name=name

Self.counter=counter

Def run(self):

打印('开始'+ self.name)

Print_time(self.name,self.counter,5)

打印('退出'+ self.name)

Def print_time(threadName,delay,counter):

计数器:

如果exitFlag:

threadName.exit()

Time.sleep(延迟)

打印('%s:%s'%(threadName,time.ctime(time.time()))))

计数器 - =1

#创建新主题

Thread1=MyThread(1,'Thread-1',1)

Thread2=MyThread(2,'Thread-2',2)

#Starting new Threads

Thread1.start()

Thread2.start()

Thread1.join()

Thread2.join()

打印('退出主线')

当您运行上述程序时,它将产生以下结果 -

启动Thread-1

启动Thread-2

Thread-1: Tue Jun 27 03: 19: 43 2017

Thread-2: Tue Jun 27 03: 19: 44 2017

Thread-1: Tue Jun 27 03: 19: 44 2017

Thread-1: Tue Jun 27 03: 19: 45 2017

Thread-2: Tue Jun 27 03: 19: 46 2017

Thread-1: Tue Jun 27 03: 19: 46 2017

Thread-1: Tue Jun 27 03: 19: 47 2017

退出Thread-1

Thread-2: Tue Jun 27 03: 19: 48 2017

Thread-2: Tue Jun 27 03: 19: 50 2017

Thread-2: Tue Jun 27 03: 19: 52 2017

退出Thread-2

退出主线程

4.同步线程

Python提供的线程模块包括一个易于使用的锁定机制,允许线程同步。通过调用lock()方法创建一个新锁,该方法返回一个新锁。

新锁对象的获取(阻塞)方法用于强制线程同步运行。可选的blocking参数控制线程是否在等待获取锁定。

如果阻塞设置为0,则线程将立即返回值0(如果无法获取锁定),如果已获取锁定,则返回1。如果阻塞设置为1,则线程将阻塞并等待锁定被释放。

新的锁对象的release()方法用于在不再需要时释放锁。

实施例

#!的/usr/bin中/python3

#save file: MyThread2.py

导入线程

导入时间

MyThread2类(threading.Thread):

Def __init __(self,threadID,name,counter):

threading.Thread .__初始化__(个体)

self.threadID=threadID

Self.name=name

Self.counter=counter

Def run(self):

打印('开始'+ self.name)

#获取锁定以同步线程

threadLock.acquire()

Print_time(self.name,self.counter,3)

#释放下一个线程的免费锁定

threadLock.release()

Def print_time(threadName,delay,counter):

计数器:

Time.sleep(延迟)

打印('%s:%s'%(threadName,time.ctime(time.time()))))

计数器 - =1

threadLock=threading.Lock()

线程=[]

#创建新主题

Thread1=MyThread2(1,'Thread-1',1)

Thread2=MyThread2(2,'Thread-2',2)

#Starting new Threads

Thread1.start()

Thread2.start()

#将线程添加到线程列表

Threads.append(线程2)

#等待所有线程完成

对于线程:中的t

T.join()

打印('退出主线')

执行上述代码时,将产生以下结果 -

启动Thread-1

启动Thread-2

Thread-1: Tue Jun 27 03: 51: 45 2017

Thread-1: Tue Jun 27 03: 51: 46 2017

Thread-1: Tue Jun 27 03: 51: 47 2017

Thread-2: Tue Jun 27 03: 51: 49 2017

Thread-2: Tue Jun 27 03: 51: 51 2017

Thread-2: Tue Jun 27 03: 51: 53 2017

退出主线程

5.多线程优先级队列

队列模块允许您创建一个可以容纳特定数量项目的新队列对象。有以下方法来控制队列 -

Get() - get()从队列中删除并返回一个项目。 Put() - put()将项添加到队列中。 Qsize() - qsize()返回当前队列中的项数。 Empty() - 如果队列为空,则empty()方法返回True;否则返回False。 Full() - 如果队列已满,则full()方法返回True;否则返回False。

实施例

#!的/usr/bin中/python3

#编码=UTF-8

导入队列

导入线程

导入时间

exitFlag=0

MyQueue类(threading.Thread):

Def __init __(self,threadID,name,q):

threading.Thread .__初始化__(个体)

self.threadID=threadID

Self.name=name

Self.q=q

Def run(self):

打印('开始'+ self.name)

Process_data(self.name,self.q)

打印('退出'+ self.name)

Def process_data(threadName,q):

虽然不是exitFlag:

queueLock.acquire()

如果不是workQueue.empty():

数据=q.get()

queueLock.release()

打印('%s处理%s'%(threadName,数据))

否则为:

queueLock.release()

Time.sleep(1)

threadList=['Thread-1','Thread-2','Thread-3']

nameList=['One','Two','Three','Four','Five']

queueLock=threading.Lock()

workQueue=queue.Queue(10)

线程=[]

threadID=1

#创建新主题

对于threadList:中的tName

Thread=MyQueue(threadID,tName,workQueue)

Thread.start()

Threads.append(线程)

threadID +=1

#填充队列

queueLock.acquire()

对于nameList:中的单词

workQueue.put(字)

queueLock.release()

#等待队列清空

虽然不是workQueue.empty():

#通知线程是时候退出

exitFlag=1

#等待所有线程完成

对于线程:中的t

T.join()

打印('退出主线')

执行上述代码时,将产生以下结果 -

启动Thread-1

启动Thread-3

Thread-3处理一个

Thread-3处理两个

Thread-3处理三

Thread-3处理四个

Thread-3处理五

退出Thread-1

退出Thread-2

退出Thread-3

宜宾新闻网 版权所有© www.yibugx.com 技术支持:宜宾新闻网 | 网站地图