2

我已经在互联网上搜索了一段时间,找到了不同的解决方案,但后来都没有真正起作用,或者对我的使用来说太复杂了。直到 2 年前我才使用 C++,所以它可能有点生疏:D

我目前正在编写一个将数据发布到 URL 的程序。它只发布数据,没有别的。为了发布我使用 curl 的数据,但它阻塞了主线程,当第一个帖子仍在运行时,将会有第二个帖子应该开始。最终,大约有 5-6 个后期操作同时运行。

现在我想将带有 curl 的帖子推送到另一个线程中。每个帖子一个线程。线程应该获取一个字符串参数,其中包含要推送的内容。

我目前坚持这一点。尝试了 Windows 的 WINAPI,但在读取参数时崩溃。(在我的示例中,第二个线程仍在运行,而主线程结束(等待系统(“暂停”))。

有一个多平台解决方案会很好,因为它可以在 windows 和 linux 下运行!

这是我当前的代码:

#define CURL_STATICLIB
#include <curl/curl.h>
#include <curl/easy.h>
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#if defined(WIN32)
    #include <windows.h>
#else
    //#include <pthread.h>
#endif

using namespace std;

void post(string post) { // Function to post it to url
    CURL *curl; // curl object
    CURLcode res; // CURLcode object
    curl = curl_easy_init(); // init curl
    if(curl) { // is curl init
        curl_easy_setopt(curl, CURLOPT_URL, "http://10.8.27.101/api.aspx"); // set url
        string data = "api=" + post; // concat post data strings
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); // post data
        res = curl_easy_perform(curl); // execute
        curl_easy_cleanup(curl); // cleanup
    } else {
        cerr << "Failed to create curl handle!\n";
    }
}

#if defined(WIN32)
    DWORD WINAPI thread(LPVOID data) { // WINAPI Thread
        string pData = *((string*)data); // convert LPVOID to string [THIS FAILES]
        post(pData); // post it with curl
    }
#else
    // Linux version
#endif

void startThread(string data) { // FUnction to start the thread
    string pData = data; // some Test
    #if defined(WIN32)
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread, &pData, 0, NULL); // Start a Windows thread with winapi
    #else
        // Linux version
    #endif
}

int main(int argc, char *argv[]) {
    // The post data to send
    string postData = "test1234567890";
    startThread(postData); // Start the thread
    system("PAUSE"); // Dont close the console window
    return EXIT_SUCCESS;
}

有人建议吗?

谢谢您的帮助!

4

3 回答 3

3

考虑使用Boost.Thread或新的C++11 线程工具(如std::thread等)。

对最初问题的代码的一些评论:

  • 如果远离 std::thread 或 boost::thread,请使用_beginthreadex(..)而不是CreateThread(..),因为后者如果与 C 运行时的某些函数一起使用会导致资源泄漏。

  • 使用CreateThread(..)时,LPTHREAD_START_ROUTINE如果传递函数的签名正确,则不需要强制转换。所以铸造它是完全错误的。

  • 已经有一些关于堆栈分配变量的生命周期的评论,以及如果将这些变量的地址传递给线程函数会发生什么。

  • 不要system("PAUSE")为了保持代码的可移植性而使用。而是使用以下代码段:

    无效 wait_for_key_press()
    {
        std::cin.clear();
        std::cin.ignore(std::cin.rdbuf()->in_avail());
        std::cin.get();
    }
于 2012-09-01T21:38:49.433 回答
1

libcurl您可能希望通过使用的操作接口来避免多线程,这使您能够在同一个(单个)线程中运行多个并发 HTTP 请求。

于 2012-09-01T21:44:57.010 回答
1

用于std::thread线程。这是一个相对较新的东西,是最新 C++11 标准的一部分,但在不久的将来它可能是最便携的线程处理方式。

看看让 5 个线程忙等待是多么容易(除非经过编译器优化):

#include<thread>
#include<vector>

int main()
{
    std::vector<std::thread> threads;
    for (int i=0; i< 5; i++)
    {
         threads.push_back(std::thread([] () {
              for (long long j=0; j < 1000000000000LL; j++) ;
         }));
    }

    for (auto & thread : threads)
    {
         thread.join();
    }
}
于 2012-09-01T21:38:52.710 回答