python中threading多线程
python中有两个处理多线程的模块thread和threading。其中thread提供了多线程底层支持的模块,以低级原始的发那个是来处理和控制线程,使用起来较为复杂;而threading基于thread进行包装,将线程操作对象化。
最基础的的多线程
我们先看一个最最基础的多线程例子
import threading
import time
class test(threading.Thread):
def __init__(self,name,delay):
threading.Thread.__init__(self)
self.name = name
self.delay = delay def run(self):
print "%s is running"%self.name
for x in range(self.delay):
time.sleep(1)
print "%s is saying hello %d"%(self.name,x) def main():
t1 = test('Thread 1',3)
t2 = test('Thread 2',2)
t1.start()
t2.start() if __name__ == '__main__':
main()
print "End of main"
输出结果如下:
Thread 1 is running
End of mainThread 2 is runningThread 1 is saying hello 0
Thread 2 is saying hello 0
Thread 1 is saying hello 1
Thread 2 is saying hello 1
Thread 1 is saying hello 2
可以看出Thread1 和Thread2基本上轮流执行的,这就是多线程的好处,否则如果顺序执行2个程序会需要2倍的时间。
start是对thread的run()的封装,在调用start()的时候,会执行run()函数。
如果把代码中的一段改成下面这样呢?
def main():
t1 = test('Thread 1',3)
t2 = test('Thread 2',2)
t1.start()
print "wait for thread1 end"
t1.join()
t2.start()
输出结果为:
wait for thread1 endThread 1 is running
Thread 1 is saying hello 0
Thread 1 is saying hello 1
Thread 1 is saying hello 2
End of mainThread 2 is runningThread 2 is saying hello 0
Thread 2 is saying hello 1
从上面可以看出,调用了t1.join()后,t2会一直等到t1执行完毕才会开始执行。
使用Queue进行多线程编程
使用线程队列
如前所述,当多个线程需要共享数据或者资源的时候,可能会使得线程的使用变得复杂。线程模 块提供了许多同步原语,包括信号量、条件变量、事件和锁。当这些选项存在时,最佳实践是转而关注于使用队列。相比较而言,队列更容易处理,并且可以使得线 程编程更加安全,因为它们能够有效地传送单个线程对资源的所有访问,并支持更加清晰的、可读性更强的设计模式。
import threading
import time
import Queue
import urllib2
import os
class test(threading.Thread):
def __init__(self,queue):
threading.Thread.__init__(self)
self.queue = queue def run(self):
while 1:
url = self.queue.get()
print self.name+"begin download"+url+"..."
self.download(url)
self.queue.task_done()
print self.name+"download completed" def download(self,url):
urlHandle = urllib2.urlopen(url)
with open(os.path.basename(url)+".html","wb")as fp:
while 1:
contents=urlHandle.read(1024)
if not contents:
break
else:
fp.write(contents)
def main():
ulrs = ["http://wiki.python.org/moin/Webprograming",
"https://www.baidu.com",
"http://wiki.python.org/moin/Documendation"] q = Queue.Queue(5)
for each in ulrs:
q.put(each) for i in range(5):
t = test(q)
t.setDaemon(True)
t.start() q.join() if __name__ == '__main__':
main()
join()
保持阻塞状态,直到处理了队列中的所有项目为止。在将一个项目添加到该队列时,未完成的任务的总数就会增加。当使用者线程调用 task_done() 以表示检索了该项目、并完成了所有的工作时,那么未完成的任务的总数就会减少。当未完成的任务的总数减少到零时,
join()
就会结束阻塞状态。
每个线程运行的时候就从队列里get一个url,这时候队列的长度就缩小1,然后完成的时候发送通知。直到队列为空的时候表示全部执行完毕。
调试的时候发现即使不要task_done()也可以得到一样的结果。但是主线程会一直阻塞着无法继续执行,所以task_done的任务是告诉主线程的当前任务完成了,并递减未完成的任务数,这样主线程才知道什么时候所有的任务都完成了,好继续执行。
使用线程池
可以自己实现一个线程池模块,也可以用已经存在的第三方线程池库,本文用的是后者,比较简单。
首先安装一个threadpool的库
pip install threadpool
然后用下面的代码完成和使用Queue一样的功能
import urllib2
import os
import threadpool def download(url):
urlHandle = urllib2.urlopen(url)
with open(os.path.basename(url)+".html","wb")as fp:
while 1:
contents=urlHandle.read(1024)
if not contents:
break
else:
fp.write(contents) def main():
ulrs = ["http://wiki.python.org/moin/Webprograming",
"https://www.baidu.com",
"http://wiki.python.org/moin/Documendation"]
thread_num=5
pool = threadpool.ThreadPool(thread_num)
requests = threadpool.makeRequests(download,ulrs)
print "put all request to thread pool"
for each in requests:
pool.putRequest(each)
pool.poll() # 处理任务队列中新的请求
pool.wait() # 阻塞用于等待所有执行结果
print "destroy all threads"
pool.dismissWorkers(thread_num,do_join=True) if __name__ == '__main__':
main()
python中threading多线程的更多相关文章
- python中threading模块详解(一)
python中threading模块详解(一) 来源 http://blog.chinaunix.net/uid-27571599-id-3484048.html threading提供了一个比thr ...
- python中的多线程【转】
转载自: http://c4fun.cn/blog/2014/05/06/python-threading/ python中关于多线程的操作可以使用thread和threading模块来实现,其中th ...
- Python中的多线程编程,线程安全与锁(二)
在我的上篇博文Python中的多线程编程,线程安全与锁(一)中,我们熟悉了多线程编程与线程安全相关重要概念, Threading.Lock实现互斥锁的简单示例,两种死锁(迭代死锁和互相等待死锁)情况及 ...
- python中的多线程
一个程序可以理解为一个进程,这个进程有其代号,可以依据这个代号将其杀死. 一个进程肯定有且只有一个主线程,他可以有很多子线程. 运行一个任务如果可以有许多子线程同时去做,当然会提高效率. 但是,在py ...
- python中的多线程和多进程
一.简单理解一下线程和进程 一个进程中可有多个线程,线程之间可共享内存,进程间却是相互独立的.打比方就是,进程是火车,线程是火车厢,车厢内人员可以流动(数据共享) 二.python中的多线程和多进程 ...
- python中threading的用法
摘自:http://blog.chinaunix.net/uid-27571599-id-3484048.html 以及:http://blog.chinaunix.net/uid-11131943- ...
- 2016/1/2 Python中的多线程(1):线程初探
---恢复内容开始--- 新年第一篇,继续Python. 先来简单介绍线程和进程. 计算机刚开始发展的时候,程序都是从头到尾独占式地使用所有的内存和硬件资源,每个计算机只能同时跑一个程序.后来引进了一 ...
- Python中的多线程编程,线程安全与锁(一)
1. 多线程编程与线程安全相关重要概念 在我的上篇博文 聊聊Python中的GIL 中,我们熟悉了几个特别重要的概念:GIL,线程,进程, 线程安全,原子操作. 以下是简单回顾,详细介绍请直接看聊聊P ...
- Python之threading多线程,多进程
1.threading模块是Python里面常用的线程模块,多线程处理任务对于提升效率非常重要,先说一下线程和进程的各种区别,如图 概括起来就是 IO密集型(不用CPU) 多线程计算密集型(用CPU) ...
随机推荐
- (转)Resources和AssetBundle(新旧版)学习
Resources: Resources的缺点:1.与显示Inspector上直接引用相比,Resources使用不方便. 2.不管你Resources上的资源是否调用了,当你发布的时候, ...
- OpenCV学习笔记十:opencv_superres模块
一,简介: 该库用于图像超分辨率重建.即通过硬件或软件的方法提高原有图像的分辨率,通过一系列低分辨率的图像来得到一幅高分辨率的图像.
- day8笔记
一.上节回顾 1,id() 内存地址2, == 比较的是值 is 比较的是内存地址 数字,字符串,有小数据池, #内存地址一样的 int -5--256 str:1,不能有空格. 2,长度不能超过20 ...
- HashMap的clear()方法和new HashMap的效率问题
最近研究Lucene的时候,遇到的用到大量Map的问题,心生好奇,想看一下在1W,10W,100W三种数据量下,new HashMap ,与 HashMap.clear()方法的效率问题. 提前说明: ...
- 转:: 刺鸟:用python来开发webgame服务端(1)
来源:http://ciniao.me/article.php?id=9 --------------- 刺鸟原创文章,转载请注明出处 在开始之前,先简单描述一下项目的特点:我要实现的是一个mm ...
- adb连接夜神模拟器
1.打开夜神模拟器,打开设置,调成手机模式,初次进入的话,进入设置,点击版本号5次,可以激活使用开发者模式,进入后打开USB调试功能 2.打开文件资源管理器,进入夜神模拟器的安装位置,在地址栏输入cm ...
- #1560 : H国的身份证号码II(dp+矩阵快速幂)
#1560 : H国的身份证号码II 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 H国的身份证号码是一个N位的正整数(首位不能是0).此外,由于防伪需要,一个N位正整 ...
- AJAX与后台交互传参的两种方式
工作中的简单总结备忘,防遗失. 第一种:直接传入json数据(后台一个一个入参对接) 1- js请求: var data = {}; data = {"infoId":infoId ...
- php var_dump()函数的详解
说明:var_dump()方法,判断一个变量的类型与长度,并输出变量的数值,如果变量有值,则输出是变量的值,并返回数据类型.显示关于一个或多个表达式的结构信息,包括表达式的类型与值.数组将递归展开值, ...
- golang 面向对象
深入理解GO语言的面向对象_Golang_脚本之家 https://www.jb51.net/article/94030.htm 深入理解GO语言的面向对象 更新时间:2016年10月04日 10:4 ...