博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python3之多线程学习
阅读量:5894 次
发布时间:2019-06-19

本文共 4470 字,大约阅读时间需要 14 分钟。

多线程优点

多线程类似于同时执行多个不同程序,多线程运行有如下优点:

1、使用线程可以把占据长时间的程序中的任务放到后台去处理。
2、用户界面可以更加吸引人,比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。
3、一些等待的任务实现上如用户输入、文件读写和网络收发数据等,多线程就有用了。可以释放一些珍贵的资源如内存占用等等。

线程中常用的两个模块为:thread、threading。thread 模块已被废弃。用户可以使用 threading 模块代替。

threading 模块创建线程

通过直接从 threading.Thread 继承创建一个新的子类,并实例化后调用 start() 方法启动新线程,即它调用了线程的 run() 方法。

import threadingimport time#继承threading.Thread类class feiGegeThread (threading.Thread):    #线程ID,线程名称,延迟时间    def __init__(self, threadID, name, delay):        threading.Thread.__init__(self);        self.threadID = threadID;        self.name = name;        self.delay = delay;    #重写run方法    def run(self):        print ("begin thread:" + self.name);        #调用外部函数        print_time(self.name, self.delay, 3);        print ("end thread:" + self.name);#定义打印时间方法:线程名字、延迟时间、打印次数def print_time(threadName, delay, counter):    while counter:        time.sleep(delay)        print ("%s: %s" % (threadName, time.ctime(time.time())));        counter -= 1;# 创建新线程thread1 = feiGegeThread(1, "Thread-1", 1);thread2 = feiGegeThread(2, "Thread-2", 2);# 开启新线程thread1.start();thread2.start();#join方法可以防止主线程提前结束。thread1.join();thread2.join();#结果begin thread:Thread-1begin thread:Thread-2Thread-1: Sun Jun 16 10:23:48 2019Thread-2: Sun Jun 16 10:23:49 2019Thread-1: Sun Jun 16 10:23:49 2019Thread-1: Sun Jun 16 10:23:50 2019end thread:Thread-1Thread-2: Sun Jun 16 10:23:51 2019Thread-2: Sun Jun 16 10:23:53 2019end thread:Thread-2

线程同步

如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。

使用 Thread 对象的 Lock 和 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间。

import threadingimport timeclass myThread (threading.Thread):    def __init__(self, threadID, name, delay):        threading.Thread.__init__(self);        self.threadID = threadID;        self.name = name;        self.delay = delay;    def run(self):        print ("begin thread: " + self.name);        # 获取锁,用于线程同步        threadLock.acquire();        print_time(self.name, self.delay, 3);        # 释放锁,开启下一个线程        threadLock.release();def print_time(threadName, delay, counter):    while counter:        time.sleep(delay);        print ("%s: %s" % (threadName, time.ctime(time.time())));        counter -= 1;#获取锁对象threadLock = threading.Lock();#盛放线程的列表threads = [];# 创建新线程thread1 = myThread(1, "Thread-1", 1);thread2 = myThread(2, "Thread-2", 2);# 开启新线程thread1.start();thread2.start();# 添加线程到线程列表threads.append(thread1);threads.append(thread2);# 等待所有线程完成,主线程才退出for t in threads:    t.join();结果:begin thread: Thread-1begin thread: Thread-2Thread-1: Sun Jun 16 10:38:27 2019Thread-1: Sun Jun 16 10:38:28 2019Thread-1: Sun Jun 16 10:38:29 2019Thread-2: Sun Jun 16 10:38:31 2019Thread-2: Sun Jun 16 10:38:33 2019Thread-2: Sun Jun 16 10:38:35 2019

瞧,打印函数一段时间内只允许一个线程操作。

线程优先级队列(Queue)

Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括先入先出的队列 Queue,后入先出的队列 LifoQueue,和优先级队列 PriorityQueue。

这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。

import queueimport threadingimport timeexitFlag = 0class myThread (threading.Thread):    def __init__(self, threadID, name, q):        threading.Thread.__init__(self);        self.threadID = threadID;        self.name = name;        self.q = q;    def run(self):        print ("begin thread:" + self.name);        process_data(self.name, self.q);        print ("end thread:" + self.name);def process_data(threadName, q):    while not exitFlag:        queueLock.acquire();        if not workQueue.empty():            data = q.get();            queueLock.release();            print ("%s processing %s" % (threadName, data));        else:            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);threads = [];threadID = 1;# 创建新线程for tName in threadList:    thread = myThread(threadID, tName, workQueue);    thread.start();    threads.append(thread);    threadID += 1;# 填充队列queueLock.acquire();for word in nameList:    workQueue.put(word);queueLock.release();# 等待队列清空while not workQueue.empty():    pass# 通知线程是时候退出exitFlag = 1;# 等待所有线程完成for t in threads:    t.join();#结果:begin thread:Thread-1begin thread:Thread-2begin thread:Thread-3Thread-3 processing OneThread-2 processing TwoThread-3 processing ThreeThread-1 processing FourThread-2 processing Fiveend thread:Thread-3end thread:Thread-1end thread:Thread-2

转载于:https://www.cnblogs.com/feiqiangsheng/p/11029849.html

你可能感兴趣的文章
mysql client命令行选项
查看>>
vc遍历网页表单并自动填写提交 .
查看>>
配置ORACLE 11g绿色版客户端和PLSQL远程连接环境
查看>>
ASP.NET中 DataList(数据列表)的使用前台绑定
查看>>
Linux学习之CentOS(八)--Linux系统的分区概念
查看>>
主域控制器的安装与配置步骤与方法
查看>>
JavaScript---事件
查看>>
Android NDK入门实例 计算斐波那契数列一生成jni头文件
查看>>
c/c++性能优化--I/O优化(上)
查看>>
将HTML特殊转义为实体字符的两种实现方式
查看>>
jquery 保留两个小数的方法
查看>>
网站架构设计的误区
查看>>
iis 故障导致网站无法访问
查看>>
C++ 基础笔记(一)
查看>>
System.Func<>与System.Action<>
查看>>
asp.net开源CMS推荐
查看>>
csharp skype send message in winform
查看>>
MMORPG 游戏服务器端设计--转载
查看>>
《星辰傀儡线》人物续:“灭世者”、“疯狂者”、“叛逆者”三兄妹
查看>>
安装系统字体
查看>>