Я пишу сканер в C ++, функция crawler
загружает сайт и извлекает из него все ссылки. Я хотел, чтобы это запустить функцию crawler
в нескольких потоках, каждый поток с различными параметрами, а также я хочу указать количество потоков. Таким образом, в начале программы я хочу указать количество потоков, затем при запуске программы мне нужно, чтобы каждый поток запускался с разными параметрами, чтобы я мог одновременно загружать указанное количество веб-сайтов. Я знаю, как выполнять базовую многопоточность, но мне нужно указать количество потоков в начале программы. Так есть ли библиотеки, которые позволили бы мне это сделать? Или это возможно с std::thread
?
#include <sstream>
#include <iostream>
#include <string>
#include "gumbo.h"#include <curl/curl.h>
using namespace std;
//extract links
static void search_for_links(GumboNode* node) {
if (node->type != GUMBO_NODE_ELEMENT) {
return;
}
GumboAttribute* href;
if (node->v.element.tag == GUMBO_TAG_A &&
(href = gumbo_get_attribute(&node->v.element.attributes, "href"))) {
std::cout << href->value << std::endl;
}
GumboVector* children = &node->v.element.children;
for (int i = 0; i < children->length; ++i) {
search_for_links(static_cast<GumboNode*>(children->data[i]));
}
}//turn the output from libcurl in to a string
size_t write_to_string(void *ptr, size_t size, size_t count, void *stream) {
((string*)stream)->append((char*)ptr, 0, size*count);
return size*count;
}
int crawler(char url[60])
{curl_global_init( CURL_GLOBAL_ALL );
CURL * myHandle = curl_easy_init ( );//set the 'libcurl' parameters
curl_easy_setopt(myHandle, CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16");
curl_easy_setopt(myHandle, CURLOPT_AUTOREFERER, 1 );
curl_easy_setopt(myHandle, CURLOPT_FOLLOWLOCATION, 1 );
curl_easy_setopt(myHandle, CURLOPT_COOKIEFILE, "");
//set the url
curl_easy_setopt(myHandle, CURLOPT_URL, url);
//turn the output in to a string using a function
string response;
curl_easy_setopt(myHandle, CURLOPT_WRITEFUNCTION, write_to_string);
curl_easy_setopt(myHandle, CURLOPT_WRITEDATA, &response);
curl_easy_perform( myHandle );
//HTML parsing
GumboOutput* output = gumbo_parse(response.c_str());
search_for_links(output->root);return 0;
}
int main()
{
crawler("http://wikipedia.org");
return 0;
}
Вы можете создать несколько std :: threads и сохранить их в векторе. Допустим, у вас есть ваша функция
void f(int x, std::string const& y);
Затем вы можете создать вектор с потоками, выполняющими функцию с
std::vector<std::thread> threadgroup;
threadgroup.emplace_back(1, "abc");
threadgroup.emplace_back(2, "def");
Это запустит два потока в векторе. Обязательно присоединяйтесь к ветке перед выходом.
Я думаю, что вам на самом деле понадобится определенное количество потоков, обрабатывающих контейнер со ссылками. Каждый поток загружает страницу и добавляет новые ссылки в контейнер. Когда одна страница обрабатывается, она получает новую ссылку из контейнера.
Других решений пока нет …