带参数的 C++ 简单线程(无 .net)

Posted

技术标签:

【中文标题】带参数的 C++ 简单线程(无 .net)【英文标题】:C++ Simple thread with parameter (no .net) 【发布时间】:2012-09-01 21:34:36 【问题描述】:

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

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

现在我想将带有 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;

有什么建议吗?

感谢您的帮助!

【问题讨论】:

pDatastartThread 中有自动存储;将指针传递给它不会阻止它在超出范围时被销毁。你不应该这样做。 【参考方案1】:

考虑使用Boost.Thread 或新的C++11 threading facilities(如std::thread 等)。

对第一个问题的代码的一些说明:

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

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

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

不要使用system("PAUSE") 来保持代码的可移植性。而是使用以下 sn-p:

无效 wait_for_key_press() std::cin.clear(); std::cin.ignore(std::cin.rdbuf()->in_avail()); std::cin.get();

【讨论】:

我想我现在会使用 std::thread 。我已经听说过 Boost.Thread,但集成起来看起来很复杂。由于跨平台兼容性,我在这里并没有真正使用 IDE。 如果您已经拥有 C++11 线程功能,那么无论如何这是首选的方式! 系统暂停只是为了测试。以后使用时会编译成.dll或.so文件作为程序的插件。【参考方案2】:

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();
    

【讨论】:

mhh 看起来我有一个较旧的 C++ 标准。线程:没有这样的文件或目录! @MarcVollmer 您可以从 Microsft 网站下载最新的 Visual Studio 2012 候选版本(暂时免费)。支持std::thread @MarcVollmer 真的吗?我以为 MinGW 还不支持std::thread【参考方案3】:

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

【讨论】:

以上是关于带参数的 C++ 简单线程(无 .net)的主要内容,如果未能解决你的问题,请参考以下文章

无法调用带参数的线程函数

C++类-带参数的构造函数

C++类-带参数的构造函数

求 linux下 c++高手,命令行传参数的题,

线程的启动(转)

基于C++代码的UE4学习—— 带一个参数的FParamDelegateSignature动态代理与函数指针