老男孩python学习自修第二十三天【多线程】
1. 线程的创建与运行
#!/usr/bin/env python # _*_ coding:UTF-8 _*_ from threading import Thread def foo(param1, param2): print "{0}{1}".format(param1, param2) if __name__ == "__main__": print "main thread running" thread = Thread(target=foo, args=(123, "abc")) print "before new thread running" thread.start() print "after new thread running"
结果:
/Users/liudaoqiang/PycharmProjects/numpy/venv/bin/python /Users/liudaoqiang/Project/python_project/day23/thread_test.py main thread running before new thread running 123abcafter new thread running Process finished with exit code 0
2.线程常用API
thread.getName() 获取线程的名称,子线程的名称默认为Thread-n
thread.setName(name) 设置线程的名称
thread.isDaemon() 是否为守护线程,是守护线程则主线程结束,子线程结束;子线程不是守护线程则主线程等待子线程结束后才结束
thread.setDaemon(bool) 设置是否为守护线程
thread.start()
thread.run()
thread.join(timeout)
#!/usr/bin/env python # _*_ coding:UTF-8 _*_ from threading import Thread import time def bar(): for item in range(100): print item time.sleep(1) if __name__ == "__main__": print "main thread running" thread = Thread(target=bar, args=()) thread.setDaemon(True) print "before %s running" % thread.getName() thread.start() print "after %s running" % thread.getName() time.sleep(5)
结果:
/Users/liudaoqiang/PycharmProjects/numpy/venv/bin/python /Users/liudaoqiang/Project/python_project/day23/thread_test.py main thread running before Thread-1 running after Thread-1 running 0 1 2 3 4 Process finished with exit code 0
3.join()的使用
#!/usr/bin/env python # _*_ coding:UTF-8 _*_ from threading import Thread import time def bar(): for item in range(100): print item time.sleep(1) if __name__ == "__main__": print "main thread running" thread = Thread(target=bar, args=()) thread.setDaemon(True) print "before %s running" % thread.getName() thread.start() thread.join(10) print "after %s running" % thread.getName() time.sleep(5)
结果:
/Users/liudaoqiang/PycharmProjects/numpy/venv/bin/python /Users/liudaoqiang/Project/python_project/day23/thread_test.py main thread running before Thread-1 running 0 1 2 3 4 5 6 7 8 9 after Thread-1 running 10 11 12 13 14 Process finished with exit code 0
注意:
(1)thread.join(timeout) 表示主线程等待子线程运行timeout后,主线程再运行
4.自定义线程类
day23
__init__.py
mythread.py
mythread_test.py
mythread.py
#!/usr/bin/env python # _*_ coding:UTF-8 _*_ from threading import Thread class MyThread(Thread): def run(self, ): print self.getName() + " is running" Thread.run(self)
mythread_test.py
#/usr/bin/env python # _*_ coding:UTF-8 _*_ from day23 import mythread def foo(param): print "Thread running with %s" % param if __name__ == "__main__": thread = mythread.MyThread(target=foo, args=("abc", )) thread.start()
结果:
/Users/liudaoqiang/PycharmProjects/numpy/venv/bin/python /Users/liudaoqiang/Project/python_project/day23/mythread_test.py Thread-1 is running Thread running with abc Process finished with exit code 0
注意:
(1)自定义线程类需要继承threading.Thread类并实现run(),在run()中调用父类的run()
(2)使用自定义的类需要导入,导入和使用为:
from package import module
mythread = module.MyThread()
5.生产者-消费者模型
#!/usr/bin/env python # _*_ coding:UTF-8 _*_ from threading import Thread from Queue import Queue import time class Producer(Thread): def __init__(self, name, queue): self.__name = name self.__queue = queue super(Producer, self).__init__() def run(self): while True: if self.__queue.qsize() <= 10: self.__queue.put("包子") print "%s 生产了一个包子" % (self.__name) else: time.sleep(1) super(Producer,self).run() class Consumer(Thread): def __init__(self, name, queue): self.__name = name self.__queue = queue super(Consumer,self).__init__() def run(self): while True: if not self.__queue.empty(): self.__queue.get() print "%s 消费了一个包子" % (self.__name) super(Consumer,self).run() if __name__ == "__main__": queue = Queue(maxsize=200) for item in range(3): name = "producer %d" % item producer = Producer(name, queue) producer.start() for item in range(100): name = "consumer %d" % item consumer = Consumer(name, queue) consumer.start()
结果:
producer 1 生产了一个包子 consumer 42 消费了一个包子producer 1 生产了一个包子 consumer 42 消费了一个包子 producer 1 生产了一个包子consumer 42 消费了一个包子 producer 1 生产了一个包子 consumer 99 消费了一个包子producer 1 生产了一个包子 producer 1 生产了一个包子 consumer 94 消费了一个包子 producer 1 生产了一个包子
6.线程安全锁
#!/usr/bin/env python # _*_ coding:UTF-8 _*_ import threading import time num = 0 def run(): lock.acquire() global num num += 1 lock.release() time.sleep(0.01) print "%s runing: num is %d" % (thread.getName(), num) if __name__ == "__main__": lock = threading.Lock() for item in range(2000): thread = threading.Thread(target=run, args=()) thread.setDaemon(False) thread.start()
部分结果:
Thread-1670 runing: num is 1669 Thread-1671 runing: num is 1669 Thread-1674 runing: num is 1674Thread-1674 runing: num is 1674 Thread-1674 runing: num is 1674 Thread-1681 runing: num is 1680 Thread-1681 runing: num is 1681 Thread-1685 runing: num is 1684 Thread-1685 runing: num is 1684 Thread-1686 runing: num is 1685 Thread-1687 runing: num is 1685 Thread-1697 runing: num is 1696Thread-1697 runing: num is 1696 Thread-1697 runing: num is 1697Thread-1698 runing: num is 1697
注意:
(1)一个线程没有没有进行sleep,则执行100条指令
(2)线程之间是共享内存资源的,为了线程的安全,需要增加线程锁
(3)双重加锁需要使用lock = threading.RLock()
其他锁:
#!/usr/bin/env python # _*_ coding:UTF-8 _*_ import threading import time num = 0 def run(): lock.acquire() global num num += 1 lock.release() time.sleep(0.01) print "%s runing: num is %d" % (thread.getName(), num) if __name__ == "__main__": #这时普通锁 lock = threading.Lock() #这是双重锁 lock = threading.RLock() #这时多个线程共享锁 lock = threading.BoundedSemaphore(4) for item in range(2000): thread = threading.Thread(target=run, args=()) thread.setDaemon(False) thread.start()
7.生产者-消费者模型的通信事件
#!/usr/bin/env python # _*_ coding:UTF-8 _*_ import threading import time def producer(): print "生产者:正在等待消费者到来..." # 生产者在这里等待,等待消费者将标识位设置位True event.wait() # 生产者开始工作后,要将标识为清空,即设置位False,让消费者处于等待状态 event.clear() print "生产者:开始生产包子" time.sleep(5) print "生产者:包子生产完成" # 生产完成,将标识位设置位True,让消费者不处于等待状态 event.set() def consumer(): print "消费者:还未到来..." time.sleep(3) print "消费者:来了..." # 将标识位设置位True,让消费者开始工作 event.set() print "消费者:我要包子" # 这里需要延时 time.sleep(1) # 通过判断生产者是否将标识位设置位True while True: if event.isSet(): print "消费者:谢谢" break else: print "消费者:好了吗" time.sleep(1) if __name__ == "__main__": #定义生产者和消费者的通信事件 event = threading.Event() producer = threading.Thread(target=producer, args=()) producer.start() consumer = threading.Thread(target=consumer, args=()) consumer.start()
结果:
/Users/liudaoqiang/PycharmProjects/numpy/venv/bin/python /Users/liudaoqiang/Project/python_project/day23/thread_set_test.py 生产者:正在等待消费者到来... 消费者:还未到来... 消费者:来了... 消费者:我要包子生产者:开始生产包子 消费者:好了吗 消费者:好了吗 消费者:好了吗 消费者:好了吗 生产者:包子生产完成 消费者:谢谢 Process finished with exit code 0
注意:
(1)该通信事件的目的是生产者可以控制消费者是否等待;消费者也可以控制生产者是否等待
老男孩python学习自修第二十三天【多线程】的更多相关文章
- 老男孩python学习自修第二十四天【多进程】
1. 体验多进程的运行速度 #!/usr/bin/env python # _*_ coding:UTF-8 _*_ from multiprocessing import Pool import t ...
- 老男孩 python学习自修第二十二天【文件上传与下载】
1.使用socket实现文件上传 server.py #!/usr/bin/env python # _*_ coding:UTF-8 _*_ import os import SocketServe ...
- 老男孩python学习自修第十三天【md5加密】
示例代码如下: hashlib_test.py #!/usr/bin/env python # _*_ coding:UTF-8 _*_ import hashlib def genPasswd(na ...
- 老男孩python学习自修【第二天】字符串用法
实时处理增量日志最佳实践 主要使用f.seek()和f.tell()实现 字符串处理函数: s.find(substr, start, end) 查找子字符串,找不到则返回-1,找到则返回对应的索引 ...
- Python学习笔记第二十三周(Flask架构)
目录: 一.变量引用 内容: 备注:PyCharm小技巧,comm+alt+l 自动修改格式,comm+alt+return 向上添加新行 一.变量引用 1.url生成 from flask im ...
- 老男孩python学习自修第十六天【常用模块之sys和os】
例子: sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys. ...
- 老男孩python学习自修第十九天【异常处理】
1.常见的错误 TypeError 类型错误 NameError 没有该变量 ValueError 不期望的值 AttributeError 没有该属性 UnboundLocalError 没有该局部 ...
- 老男孩python学习自修第十八天【面向对象】
1.类与对象(构造方法与实例化) #!/usr/bin/env python # _*_ coding:UTF-8 _*_ class Province: def __init__(self, nam ...
- 老男孩python学习自修第十七天【装饰器】
装饰器:在某个方法执行前后去执行其他新定义的行为 例如: #!/usr/bin/env python # _*_ coding:UTF-8 _*_ def before_say_hello(): pr ...
随机推荐
- ubantu搭建oj——第一天(6.11)
oj第一份作业: 按照DMOJ的文档将代码搬运到ubantu上 sudo apt install git gcc g++ make python-dev libxml2-dev libxslt1-de ...
- 初学Python——文件操作第二篇
前言:为什么需要第二篇文件操作?因为第一篇的知识根本不足以支撑基本的需求.下面来一一分析. 一.Python文件操作的特点 首先来类比一下,作为高级编程语言的始祖,C语言如何对文件进行操作? 字符(串 ...
- CF1103D Professional layer 状压DP
传送门 首先对于所有数求gcd并求出这个gcd含有的质因子,那么在所有数中,只有这一些质因子会对答案产生影响,而且对于所有的数,每一个质因子只会在一个数中被删去. 质因子数量不会超过\(11\),所以 ...
- jumpserver安装
一. 准备 Python3 和 Python 虚拟环境 1.1 安装依赖包 yum -y install wget sqlite-devel xz gcc automake zlib-devel o ...
- WPF PasswordBox不支持绑定解决方法
原文:WPF PasswordBox不支持绑定解决方法 PasswordBox的Password属性因为安全原因不支持直接绑定,可以使用依赖属性实现.直接插入代码 public class Passw ...
- 缓存子系统如何设计(Cachable tag, Memcache/redis support, xml config support, LRU/LFU/本地缓存命中率)
大家对这段代码肯定很熟悉吧: public List<UserInfo> SearchUsers(string userName) { string cacheKey=string.For ...
- [WPF]如何使用代码创建DataTemplate(或者ControlTemplate)
1. 前言 上一篇文章([UWP]如何使用代码创建DataTemplate(或者ControlTemplate))介绍了在UWP上的情况,这篇文章再稍微介绍在WPF上如何实现. 2. 使用Framew ...
- Fastreport.net 如何在开发MVC应用程序时使用报表
当你使用MVC模板创建自己的Web项目,会出现一个合理的问题 - 如何在其中使用FastReport.Net Web报表? 在这篇文章中,我会为你演示如何做到这一点. 由于在MVC体系结构中,视图与逻 ...
- B. School Marks(典型贪心)
链接 [https://codeforces.com/contest/540/problem/B] 题意 某个人有n门成绩,k门已知,剩下的他可以个瞎改,但有个要求,最后分数和不超过x,且每门成绩不超 ...
- AtCoder Beginner Contest 122 D - We Like AGC (DP)
D - We Like AGC Time Limit: 2 sec / Memory Limit: 1024 MB Score : 400400 points Problem Statement Yo ...