0

我目前正在使用 Threading/workpool 测试一些东西;我创建了 400 个线程,它们总共下载了 5000 个 URL... 问题是 400 个线程中的一些线程正在“冻结”,当查看我的进程时,我看到每次运行都会冻结 +- 15 个线程,并且最终在一段时间后1比1关闭。

我的问题是是否有一种方法可以让某种“计时器”/“计数器”在 x 秒后没有完成时杀死一个线程。

# download2.py - Download many URLs using multiple threads.
import os
import urllib2
import workerpool
import datetime
from threading import Timer

class DownloadJob(workerpool.Job):
    "Job for downloading a given URL."
    def __init__(self, url):
        self.url = url # The url we'll need to download when the job runs
    def run(self):
        try:
            url = urllib2.urlopen(self.url).read()
        except:
            pass

# Initialize a pool, 400 threads in this case
pool = workerpool.WorkerPool(size=400)

# Loop over urls.txt and create a job to download the URL on each line
print datetime.datetime.now()
for url in open("urls.txt"):
    job = DownloadJob(url.strip())
    pool.put(job)

# Send shutdown jobs to all threads, and wait until all the jobs have been completed
pool.shutdown()
pool.wait()
print datetime.datetime.now()
4

2 回答 2

1

问题是400个线程中的一些正在“冻结”......

这很可能是因为这条线......

url = urllib2.urlopen(self.url).read()

默认情况下,Python 将永远等待远程服务器响应,因此如果您的 URL 指向忽略SYN数据包的服务器,或者速度非常慢,则线程可能会被永远阻塞。

您可以使用设置线程等待远程主机响应的时间限制的timeout参数...urlopen()

url = urllib2.urlopen(self.url, timeout=5).read() # Time out after 5 seconds

...或者您可以socket.setdefaulttimeout()通过将这些行放在代码顶部来全局设置它...

import socket
socket.setdefaulttimeout(5) # Time out after 5 seconds
于 2013-06-12T19:01:13.237 回答
0

urlopen 接受一个超时值,我认为这将是处理它的最佳方式。

但我同意评论者的观点,即 400 个线程可能太多了

于 2013-06-12T19:00:51.783 回答