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) ...
随机推荐
- linux各种路径小结
man路径 /etc/manpath.config $MANPATH include路径 $C_INCLUDE_PATH $CPLUS_INCLUDE_PATH 动态链接库的路径 $LD_LIBRAR ...
- 分享一个编译期输出TODO,FIXME列表的宏
效果,双击能跳到相应位置: >------ Build started: Project: TestVS2013, Configuration: Debug Win32 ------ > ...
- greenlet:轻量级的并发编程
1 关于greenlet greelet指的是使用一个任务调度器和一些生成器或者协程实现协作式用户空间多线程的一种伪并发机制,即所谓的微线程. greelet机制的主要思想是:生成器函数或者协程函数中 ...
- 进程 vs. 线程
我们介绍了多进程和多线程,这是实现多任务最常用的两种方式.现在,我们来讨论一下这两种方式的优缺点. 首先,要实现多任务,通常我们会设计Master-Worker模式,Master负责分配任务,Work ...
- mac中一一些常用的命令
本文转载至 http://blog.csdn.net/chen505358119/article/details/9244701 这里主要讲的是mac中的一些命令,怕忘记了所以记在这里. 1.首先 ...
- poj1837
Balance Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 12995 Accepted: 8142 Descript ...
- 【BZOJ1912】[Apio2010]patrol 巡逻 树形DP
[BZOJ1912][Apio2010]patrol 巡逻 Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示 ...
- git push 推送大文件失败的处理办法
不小心把数据库备份文件放到git目录里了,导致无法上传代码. 首先参考了 这篇文章 http://www.cnblogs.com/qmmq/p/4604862.html. 按照文中一开始说的去做,可还 ...
- Java线程的5种状态及切换
ava中的线程的生命周期大体可分为5种状态. 1. 新建(NEW):新创建了一个线程对象. 2. 可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方 ...
- Python3.6全栈开发实例[019]
19.干掉主播.现有如下主播收益信息, 按照要求, 完成相应操作:(1)计算主播平均收益值 sum = 0 for i in zhubo.values(): sum +=i print(round(s ...