我的问题再次提出了一些问题。希望找到一个更聪明的人,并且知道这个......:D
我现在遇到线程问题,当打开(1,1000)范围内的线程网址时,我很想看到所有不同的网址。只有当我运行代码时,我才会得到很多双变量(可能因为爬行速度很快)。无论如何这是我的代码:我试着看看它是哪个线程,但我得到了双打。
import threading
import urllib2
import time
import collections
results2 = []
def crawl():
var_Number = thread.getName().split("-")[1]
try:
data = urllib2.urlopen("http://www.waarmaarraar.nl").read()
results2.append(var_Number)
except:
crawl()
threads = []
for n in xrange(1, 1000):
thread = threading.Thread(target=crawl)
thread.start()
threads.append(thread)
# to wait until all three functions are finished
print "Waiting..."
for thread in threads:
thread.join()
print "Complete."
# print results (All numbers, should be 1/1000)
results2.sort()
print results2
# print doubles (should be [])
print [x for x, y in collections.Counter(results2).items() if y > 1]
但是,如果我在xrange行的正下方添加time.sleep(0.1),则不会出现那些双精度数。虽然这确实减慢了我的程序。有人知道更好的解决方法吗?
答案 0 :(得分:0)
根据Thread.getName()上的文档,这是正确的行为。
如果您想为每个线程指定一个唯一的名称,则必须使用name attribute进行设置。
根据您最终的期望,替换
for n in xrange(1, 1000):
thread = threading.Thread(target=crawl)
thread.start()
threads.append(thread)
与
for n in xrange(1, 1000):
thread = threading.Thread(target=crawl)
thread.name = n
thread.start()
threads.append(thread)
和var_Number = thread.getName().split("-")[1]
var_Number = thread.name
可以帮助您。
修改强>
经过一些测试后,另一个线程可以重用用户自定义名称,因此传递n
的唯一方法是使用threading.Thread()
的args
或kwargs
。<登记/>
这种行为是有道理的,如果我们需要在Thread中使用某种数据,正确传递它,不要试图把它放在它不属于的地方。
答案 1 :(得分:0)
在异常处理程序中对crawl()
进行递归调用。如果出现错误,同一个线程会多次运行该函数。因此,results2
可能会多次包含相同的var_Number
。如果添加time.sleep(.1)
(暂停);您的脚本消耗较少的资源,例如,打开的fds数量,运行的线程以及对远程服务器的请求更有可能成功。
默认线程名称也可能重复。如果线程退出;另一个线程可能具有相同的名称,例如,如果实现使用.ident
属性来生成名称。
注意: