Linux企業級專案實踐之網路爬蟲(18)——佇列處理

尹成發表於2014-08-31
所有的URL都接受管理,並在此進行流動。URL從管理模組的儲存空間開始,一直到最後輸出給磁碟上的URL索引,都由此部分排程。
首先,給出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;
    }
}


相關文章