我正在创建一个简单的网络蜘蛛。它所做的只是接受一个URL,下载HTML并提取剩余的URL。然后,它会为每个新URL重复此过程。我还确保我不会两次访问同一个网址,而且我限制了并发下载的数量。
每个唯一的网址都已用尽(可能会运行数天,数周或直到我死了之后),我想执行一项操作,例如更新用户界面或只是退出应用程序。
问题是,我不知道如何检测最后一个线程何时完成运行。
此线程问题是否已解决?我看错了吗?
一种想法是让每个线程保持活着,直到它的所有子节点完成(加入)。问题是线程数呈指数增长。对于这样一个长期运行的过程,它会很快耗尽OS资源。
答案 0 :(得分:2)
我不确定我们在说什么语言,所以我会说一般。
您需要为每个网址提供数据结构,以跟踪从中生成的“子网页”数量。每当一个URL被蜘蛛网时,它将具有“父”数据结构。每当找到新页面时,都会将其添加到父级的树计数中。每当一个页面被蜘蛛网时,父树的树数就会减少。这需要以同步的方式完成,因为多个线程将更新它。
您可能确实想要保存整个网址结构。根URL“http://foo.x/”具有指向“/1.html”和“/2.html”的链接,因此它的子计数为2.根URL具有null
父级和“ 1“和”2“具有根的父级。当“1.html”被蜘蛛网时,根的子计数减少到1.但如果“1.html”中有3个链接,那么根的计数会增加到4.如果你想跟踪树然后“1.html”子计数到3等。然后当“1.html”的一个孩子被蜘蛛攻击时,“1.html”的计数变为2,根URL的计数变为3。
你肯定不想要保持线程,然后在你提到后加入 - 你的线程计数会爆炸。您应该使用线程池并将URL提交到池中,每个URL都与URL树中的关联节点一起提交到池中,以便它们可以被相同的线程抓取。
当一个URL被蜘蛛网,并且子计数变为0时,您知道您已经抓住整个树,并且可以从工作列表中删除URL并将其移动到完成列表。同样,这些列表需要同步,因为多个线程将在它们上运行。
希望这有所帮助。