首先,给出URL调度的一般过程,如图所示。
其流程的各个具体操作,后面详述。
要实现前面DNS的无重复有效请求,那么在这个部分里设置一个Nsite类,实现这样的功能:当一个站点请求过DNS后,就把返回的IP保存到这个类里,那么再有这个站点内的URL出现(域名部分相同),就可以使用这个IP,而不必重复请求。
为了从一个URL中很快的找到其对应的Nsite还应该设置一个hash表,
里面存放着所有Nsite站点,这样,一个URL可以通过采用计算其域名的哈希值就快速的找到对应的站点Nsite。如:
NamedSite *namedSiteList;
namedSiteList = new NamedSite[内存中的站点数];
如果这个站点没有请求过DNS,那么就加到一个循环队列dnssite中,随时等待main( )中对其提出调度。如果有就转移到IPSite中,如果这个IPSite已经加到了okSite,那么,就把URL打到tab中。随时等待main( )调度抓取。
void push_surlqueue(Surl *url) { if (url != NULL && surl_precheck(url)) { SPIDER_LOG(SPIDER_LEVEL_DEBUG, "I want this url: %s", url->url); pthread_mutex_lock(&sq_lock); surl_queue.push(url); if (surl_queue.size() == 1) pthread_cond_signal(&sq_cond); pthread_mutex_unlock(&sq_lock); } } Url * pop_ourlqueue() { Url *url = NULL; pthread_mutex_lock(&oq_lock); if (!ourl_queue.empty()) { url = ourl_queue.front(); ourl_queue.pop(); pthread_mutex_unlock(&oq_lock); return url; } else { int trynum = 3; struct timespec timeout; while (trynum-- && ourl_queue.empty()) { get_timespec(&timeout, 500); /* 0.5s timeout*/ pthread_cond_timedwait(&oq_cond, &oq_lock, &timeout); } if (!ourl_queue.empty()) { url = ourl_queue.front(); ourl_queue.pop(); } pthread_mutex_unlock(&oq_lock); return url; } }