老男孩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 ...
随机推荐
- Idea自带工具解决冲突
1:产生冲突 2:解决冲突 解决冲突具体操作: 手动合并代码: 此时点击的是local的>:点击changes的X则合并效果为: 也可以两侧都点击>.结果为: 也可以都点击X,结果为: 最 ...
- @ConfigurationProperties 配置详解
文章转自 https://blog.csdn.net/qq_26000415/article/details/78942494 前言新的一年到了,在这里先祝大家新年快乐.我们在上一篇spring bo ...
- 环境配置 jupyter代码自动补全
自动补全 参考链接: https://www.lefer.cn/posts/15473/
- 移动前端webApp开发点滴积累20140524
#webApp开发几点体会(移动前端) ##前言 本文旨在记录本人涉足移动webApp开发的几点体会,欢迎分享与指正. ##再见,IE678 移动设备,Android跟iPhone是主流,即使是win ...
- 《程序猿闭门造车》之NBPM工作流引擎 - 项目整体架构
前言: 又是一年一度的圣诞节,可这关我什么事呢 :( ,好不容易周末了,还是说说NBPM吧,前不久我发布了一篇关于工作流的文章:<程序猿闭门造车>之NBPM工作流引擎 - 开篇,很多爱好工 ...
- 基于 Django的Ajax实现 文件上传
---------------------------------------------------------------遇到困难的时候,勇敢一点,找同学朋友帮忙,找导师求助. Ajax Ajax ...
- 解决CPC撰写文档报错问题“无法获取“AxforApplication”控件的窗口句柄。不支持无窗口的 ActiveX 控件”
最近公司需要把官方CPC电子申请移植到项目中,在移植完成后,撰写文档总是出现“无法获取“AxforApplication”控件的窗口句柄.不支持无窗口的 ActiveX 控件”,另楼主头疼很久,网上寥 ...
- [python]解决Windows下安装第三方插件报错:UnicodeDecodeError: 'ascii' codec can't decode byte 0xcb in position 0:
系统:win7IDE:pycharm Python版本:2.7 安装第三方插件是报错: 报错原因与编码有关,pip把下载的临时文件存放在了用户临时文件中,这个目录一般是C:\Users\用户名\Ap ...
- python_format格式化输出、while else、逻辑运算符、编码初识
1.格式化输出 .%d %s 格式化输出:% 占位符,d 表示替换整型数,s表示要替换字符串. name = input('请输入名字:') age = input('请输入年龄:') sex = ...
- 爬虫——scrapy框架
Scrapy是一个异步处理框架,是纯Python实现的爬虫框架,其架构清晰,模块之间的耦合程度低,可拓展性强,可以灵活完成各种需求.我们只需要定制几个模块就可以轻松实现一个爬虫. 1.架构 Scra ...