【发布时间】:2013-04-29 16:48:15
【问题描述】:
假设我有一个包含 1000 个唯一 URL 的列表,我需要打开每个 URL,并且 assert 页面上有一些东西。按顺序执行此操作显然是一个糟糕的选择,因为大多数情况下程序将处于空闲状态,只是等待响应。因此,添加到线程池中,每个工作人员从主Queue 读取,并打开一个 url 进行检查。我的问题是,我要把游泳池弄多大?它是基于我的网络带宽还是其他一些指标?是否有任何经验法则,或者只是为了找到有效尺寸而反复试验?
这更像是一个理论问题,但这是我正在使用的代码的基本轮廓。
if __name__ == '__main__':
#get the stuff I've already checked
ID = 0
already_checked = [i[ID] for i in load_csv('already_checked.csv')]
#make sure I don't duplicate the effort
to_check = load_csv('urls_to_check.csv')
links = [url[:3] for url in to_check if i[ID] not in already_checked]
in_queue = Queue.Queue()
out_queue = Queue.Queue()
threads = []
for i in range(5):
t = SubProcessor(in_queue, out_queue)
t.setDaemon(True)
t.start()
threads.append(t)
writer = Writer(out_queue)
writer.setDaemon(True)
writer.start()
for link in links:
in_queue.put(link)
【问题讨论】:
-
是 I/O 绑定还是处理器绑定?如果它受 I/O 限制,请尝试使用与处理器内核数相同的线程数。
-
@RobertHarvey 我认为 I/O 绑定的东西可能会使用比内核更多的线程数,因为 CPU 在实际 IO 发生时大部分时间处于空闲状态(在这种情况下,等待网络响应)。我是不是误会了?
-
I/O 绑定意味着您正在等待 I/O。因此,除非您在处理器旋转 I/O 时有更多工作要做,否则更多线程毫无意义。
-
如果线程主要进行网络 I/O,没有重要的磁盘 I/O 或数字运算,您可能可以并行运行所有 1000 个线程。如果前 999 个 URL 访问非常慢的网络服务器,那么至少第 1000 个会很快返回。但是,我认为这是没有很好答案的问题之一。
标签: python multithreading threadpool