es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Solicitud paralela de http de LibCurl en un entorno multinúcleo.

Actualmente, estoy creando un conjunto de manejadores fáciles de curl para hacer solicitudes HTTP paralelas. Pero esto es bloqueante.

Aquí está mi implementación:

class CurlHttpClient
{
public:

private:
CURL* m_curl = nullptr;
std::mutex m_mtx;
std::stack<curl> m_poolCurlHandle;
CURL
getCurlHandleFromPool();
void pushCurlHandle(CURL* curlHandle);
};

CURL* CurlHttpClient::getCurlHandleFromPool()
{
CURL* pCurlHandle = nullptr;
std::scoped_lock lock(m_mtx);
{
if (!m_poolCurlHandle.empty())
{
pCurlHandle = m_poolCurlHandle.top();
m_poolCurlHandle.pop();
}
return pCurlHandle;
}
return curl_easy_duphandle(m_curl);
}

void CurlHttpClient::pushCurlHandle(CURL* curlHandle)
{
std::scoped_lock lock(m_mtx);
m_poolCurlHandle.push(curlHandle);
}

int CurlHttpClient::request(const std::string& requestUrl, std::string& responseBuffer)
{

CURL* curlHandle = getCurlHandleFromPool();

curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, (void*)&responseBuffer);
curl_easy_setopt(curlHandle, CURLOPT_URL, requestUrl.c_str());

CURLcode res = curl_easy_perform(curlHandle);

int httpResponseCode = 0;
curl_easy_getinfo(curlHandle, CURLINFO_RESPONSE_CODE, &httpResponseCode);
pushCurlHandle(curlHandle);
return httpResponseCode;

}

// Ejemplo de cliente
int main()
{
CurlHttpClient client;

std::thread t1([&] { std::string response; std::string url; client.request(url, response); //do something with response});
std::thread t2([&] { std::string response; std::string url; client.request(url, response); //do something with response});
std::thread t3([&] { std::string response; std::string url; client.request(url, response); //do something with response});
std::thread t4([&] { std::string response; std::string url; client.request(url, response); //do something with response});

t1.join();
t2.join();
t3.join();
t4.join();

}

Aquí puedes ver que estoy devolviendo las respuestas individualmente para cada solicitud tan pronto como se reciben.

Leí que curl multi-interface es mejor para manejar solicitudes paralelas. He visto algunos ejemplos de configuración de multi-interface y todos los ejemplos están acumulando la solicitud y disparando la multi perform. Pero no estoy seguro de cómo devolver los datos inmediatamente al cliente cuando se recibe una respuesta individual y seguir esperando que llegue otra respuesta.

¿Es útil multi-interface en mi escenario particular? Si es así, ¿cómo puedo devolver una respuesta individual inmediatamente cuando se recibe?</curl*>

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, el multi-interfaz puede ser útil en su escenario, ya que permite enviar múltiples solicitudes HTTP en paralelo sin bloquear.

    Para devolver respuestas individuales inmediatamente cuando se reciben, puede usar una combinación de curl_multi_add_handle, curl_multi_fdset, curl_multi_wait y curl_multi_perform.

    En primer lugar, debe crear un multi-handle y agregar todos los easy-handles al multi-handle usando curl_multi_add_handle. Luego, puede utilizar curl_multi_fdset y curl_multi_wait para esperar actividad en cualquiera de los descriptores de archivo asociados con el multi-handle. Una vez que hay actividad, puede llamar a curl_multi_perform para realizar cualquier solicitud pendiente. Esta función luego devolverá el número de manijas con solicitudes completadas, que puede iterar para recuperar sus respuestas utilizando curl_easy_getinfo y empujarlos a una cola u otra estructura de datos.

    Aquí hay un ejemplo de implementación:

    Tenga en cuenta que deberá modificar la clase CurlHttpClient para agregar una variable miembro multi-handle y inicializarla apropiadamente. También deberá agregar verificación y manejo de errores a la función “request” para manejar cualquier error que pueda ocurrir durante la comunicación del multi-interfaz.

Comments are closed.