2012-05-24 39 views
1

我正在创建一个简单的网络蜘蛛。它所做的只是接受一个URL,下载HTML并提取剩余的URL。然后它重复每个新URL的过程。我也确保我不会访问同一个URL两次,并限制了并发下载的数量。检测线程树完成时

在每一个唯一的URL已经耗尽(可以运行几天,几周或直到我死了和离开后)之后,我想要执行一个操作,比如更新UI或者简单地退出应用程序。

问题是,我不知道如何检测最后一个线程何时完成运行。

此线程问题是否已解决?我在看问题错了吗?

一个想法是保持每个线程活着,直到其所有的孩子完成(加入)。问题是线程的数量呈指数增长。对于这样一个长期运行的过程,它会很快耗尽操作系统资源。

回答

2

我不确定我们在说什么语言,所以我会说一般的。

您需要每个URL的数据结构,以跟踪从中生成多少个“子”页面。每当一个URL被蜘蛛攻击时,它就会有一个“父”数据结构。无论何时找到新页面,都会添加到父项的树状结构中。每当页面出现蜘蛛时,父节点树的数量就会减少。这将需要以同步的方式完成,因为多个线程将更新它。

您可能实际上想要保存整个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。

你肯定不要围绕保持线程,然后再加入你提到 - 你的线程数会爆炸。你应该使用一个线程池并提交URLs到蜘蛛池中,每一个都与URL树中的关联节点一起提交到池中,以便它们可以被相同的线程捕获。

当一个URL被蜘蛛攻击,并且孩子数量变为0时,你知道你已经爬满了整棵树,并且URL可以从工作列表中移除并移动到完成列表。同样,这些列表将需要同步,因为多个线程将对它们进行操作。

希望这有些帮助。

+0

我从其他人那里得到了类似的答案。在开始一个子线程之前简单地递增,然后递减。当计数变为零时,让该子线程启动“我已完成”的工作。谢谢! –