【问题标题】:Synchronized curl requests同步 curl 请求
【发布时间】:2015-07-10 01:35:30
【问题描述】:

我正在尝试向多个目标发出 HTTP 请求,我需要它们(几乎)同时运行。

我正在尝试为每个请求创建一个线程,但我不知道为什么 Curl 在执行时会崩溃。我为每个线程使用了一个简单的句柄,所以理论上一切都应该没问题...

有人遇到过类似的问题吗?或者有谁知道多接口是否允许您选择何时执行所有请求?

非常感谢。

编辑:

下面是代码示例:

void Clazz::function(std::vector<std::string> urls, const std::string& data)
{
    for (auto it : urls)
    {
        std::thread thread(&Clazz::DoRequest, this, it, data);
        thread->detach();
    }
}

int Clazz::DoRequest(const std::string& url, const std::string& data)
{
    CURL* curl = curl_easy_init();
    curl_slist *headers = NULL;

    headers = curl_slist_append(headers, "Expect:"); 
    headers = curl_slist_append(headers, "Content-Type: application/json");

    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());

    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt (curl, CURLOPT_FAILONERROR, 1L);

    //curlMutex.lock();
    curl_easy_perform(curl);
    //curlMutex.unlock();
    long responseCode = 404;
    curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &responseCode);

    curl_easy_cleanup(curl);
    curl_slist_free_all(headers);
}

希望对你有帮助,谢谢!

【问题讨论】:

  • 发布您的代码示例,以便我们更好地理解。据我所知,cUrl 支持多线程(操作系统?编译器?)
  • 执行此操作的两个选项都应该可以正常工作。要么使用多接口并在同一个线程中发送两个请求。或者创建两个线程并使用简单的界面。
  • 在调用 cUrl 时尝试使用互斥锁,这样您就可以将可能性范围减少到 cUrl 中的竞争条件(不幸)或您如何使用它(更不幸;))
  • 从两个不同的线程调用 curl_easy_perform 时不需要互斥锁。
  • 我刚刚编辑了问题以添加代码的 sn-p。我希望这能有所帮助。如果我取消注释锁它工作正常,但它会被序列化。我试图复制这两个参数以避免在线程使用它之前破坏刺痛的机会....但没有任何效果。

标签: c++ multithreading curl libcurl


【解决方案1】:

你在任何地方打电话给curl_global_init吗?也许在你的 main() 方法的早期?

引用http://curl.haxx.se/libcurl/c/curl_global_init.html:

此函数不是线程安全的。当程序中的任何其他线程(即共享相同内存的线程)正在运行时,您不得调用它。这不仅仅意味着没有其他线程正在使用 libcurl。因为 curl_global_init 调用了类似线程不安全的其他库的函数,它可能与使用这些其他库的任何其他线程冲突。

引用http://curl.haxx.se/libcurl/c/curl_easy_init.html:

如果您还没有调用 curl_global_init,curl_easy_init 会自动调用。这在多线程的情况下可能是致命的,因为 curl_global_init 不是线程安全的,并且可能因为没有相应的清理而导致资源问题。

听起来您没有打电话给curl_global_init,而是让curl_easy_init 为您处理。由于您同时在两个线程上执行此操作,因此您遇到了线程不安全的情况,并带来了前面提到的致命结果。

【讨论】:

  • 我认为情况并非如此。我在 main 函数的第一行调用 curl_global_init...
【解决方案2】:

能够在设备中正确调试后,您发现问题是 curl 的一个老问题。

http://curl.haxx.se/mail/lib-2010-11/0181.html

在每个 curl 句柄中使用 CURLOPT_NOSIGNAL 后,崩溃消失了。 :)

【讨论】:

    猜你喜欢
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多