python多线程问题,非setDaemon,标志位控制,线程无法结束!
先看一个严重标志位是否好使的简单例子:
这个例子运行正常,说明可以通过标志位控制子线程。
下面这个是一个深度抓取页面的爬虫,提取出首页的所有链接继续抓这些链接的内容,,控制机制和上面例子一样。但是不能正常结束。
下面加上打印信息
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
C:\Program Files\Microsoft Visual Studio 9.0\VC>G:
G:\>cd proxy
G:\proxy>python Quere.py
True
True
True
True
True
True
True
True
True
True
True
--------------------
True
True
=====================im done
17
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
<urlopen error timed out> other--exception----------in- threadget----
--------------------
True
<urlopen error (11001, 'getaddrinfo failed')> other--exception----------in- thre
adget----
--------------------
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
=====================im done
195
Exiting Main Thread
#不能正常结束,如果标志位不起作用,应该不断打印true才对,但是没有。任务管理器里线程数还是10+
困惑,,,难道是Queue join的问题?但是=====================im done都打印出来了!
from threading import Thread,Lock
import time
a = True
class A:
def __init__(self,):
t = Thread(target=self.run)
t.start()
def run(self):
print 'im starting'
while a:
print a
if __name__ == "__main__":
aa=A()
time.sleep(1)
a= False
这个例子运行正常,说明可以通过标志位控制子线程。
下面这个是一个深度抓取页面的爬虫,提取出首页的所有链接继续抓这些链接的内容,,控制机制和上面例子一样。但是不能正常结束。
#coding=utf-8
from BeautifulSoup import BeautifulSoup
import urllib2
from threading import Thread,Lock
from Queue import Queue
import time
import socket
socket.setdefaulttimeout(5)
flag = True#标志位,控制子线程结束
class Fetcher:#封装的抓取网页的线程,处理结果的线程
def __init__(self,th_num):
self.opener = urllib2.build_opener(urllib2.HTTPHandler)
self.q_req = Queue() #任务队列
self.q_ans = Queue() #抓取结果处理队列
self.urls = []#返回下一深度要抓取的url
for i in range(th_num):#启动抓取线程
t = Thread(target=self.thread_get)
t.start()
for i in range(0,1):
t = Thread(target=self.thread_put)
t.start()
def join(self): #需等待两个队列完成
self.q_req.join()
self.q_ans.join()
print '=====================im done'#这个运行的时候也能打印出来。
def push(self,req):#往任务队列装任务
self.q_req.put(req)
def thread_put(self):#负责结果处理,将页面中的url存到sel.url里面
while flag:
print flag#调试用,如果这个线程没有结束,应该不断的打印flag才对
try:
url = self.q_ans.get()
self.urls.extend(url)
except Exception ,e:
print e,'other,excp========in=put'
finally:
self.q_ans.task_done()
def thread_get(self):
while flag:
print flag
try:
req = self.q_req.get()
urls = []
ans = self.opener.open(req).read()#抓取页面
soup = BeautifulSoup(ans)#解析页面
for a in soup.findAll('a'):#提取页面的所有链接
try:
if a['href'].startswith('http'):
urls.append(a['href'])
except Exception,ex:
print ex,'========================Exception=in=soup=findAll'
self.q_ans.put(urls)#将连接放入结果处理队列,让put线程去处理
except Exception, e:
print e,'other--exception----------in- threadget----'
finally:
print '--------------------'
self.q_req.task_done()
print "----------get---quiting"#这个看不到打印
def run(f,links):#作用是在下一轮抓取前清空urls,填装下一轮的任务,并等待任务完成。
f.urls = []
for url in links:
f.push(url)
f.join()
return f.urls
if __name__ == "__main__":
links = ['http://www.kingdowin.com/',]
deep = 2#要抓取的深度
f = Fetcher(10)
while deep > 0:#在这里结合run函数控制抓取深度
urls = run(f,links)
deep -= 1
links = urls
print len(links)
time.sleep(1)
flag = False #关闭线程
time.sleep(1)
print "Exiting Main Thread"#这一行会被打印出来
#每次运行,到这里,光标不动,通过任务管理器查看python的线程数13个
#线程虽然在,但不打印信息了
下面加上打印信息
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
C:\Program Files\Microsoft Visual Studio 9.0\VC>G:
G:\>cd proxy
G:\proxy>python Quere.py
True
True
True
True
True
True
True
True
True
True
True
--------------------
True
True
=====================im done
17
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
<urlopen error timed out> other--exception----------in- threadget----
--------------------
True
<urlopen error (11001, 'getaddrinfo failed')> other--exception----------in- thre
adget----
--------------------
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
--------------------
True
True
=====================im done
195
Exiting Main Thread
#不能正常结束,如果标志位不起作用,应该不断打印true才对,但是没有。任务管理器里线程数还是10+
困惑,,,难道是Queue join的问题?但是=====================im done都打印出来了!
...全文
相关推荐
python中threading开启关闭线程操作
Python中的`threading`模块是实现多线程编程的关键,它提供了一种方式来执行并发任务,从而提高程序的效率。本文将详细讲解如何在Python中开启和关闭线程,以及如何实现线程的控制。
Python常用模块 之 threading模块(一) 线程模块及其使用
Python常用模块 之 threading模块(一) 线程模块及其使用
判断Threading.start新线程是否执行完毕的实例
在Python的多线程编程中,`threading`模块提供了创建和管理线程的功能。
正交拉丁超立方(OLHC)分组与实验设计(DOE)评估的优化Python实现.rar
正交拉丁超立方(OLHC)分组与实验设计(DOE)评估的优化Python实现.rar
Java微服务如何拆解审计日志查询服务
标题:Java微服务如何拆解审计日志查询服务 内容概要:围绕缓存策略、任务调度、回压控制和审计追踪,拆解Java微服务如何拆解审计日志查询服务的实现细节。 xdronline.com xdrea.com 9g.xinmei6.com xinghaohuanbao.com m.xiker66.com


