传递字符串作为线程启动例程参数:c++



参考http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#SCHEDULING

我试图在c++中创建两个线程,并试图将字符串作为参数传递给Thread Start Routine。根据定义,Thread Start Routine参数只能是(void *)类型:

int pthread_create(pthread_t * thread, 
                       const pthread_attr_t * attr,
                       void * (*start_routine)(void *), 
                       void *arg);

但是我得到下面的error:

$ make
g++ -g -Wall Trial.cpp -o Trial
Trial.cpp: In function `int main()':
Trial.cpp:22: error: cannot convert `message1' from type `std::string' to type `void*'
Trial.cpp:23: error: cannot convert `message2' from type `std::string' to type `void*'
Makefile:2: recipe for target `Trial' failed
make: *** [Trial] Error 1

代码

#include <iostream>
#include <pthread.h>
#include <string>

using namespace std;
void *print_message_function( void *ptr );

int main()
{
    pthread_t thread1, thread2;
    string message1 = "Thread 1";
    string message2 = "Thread 2";
    int  iret1, iret2;

     iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
     iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);

     pthread_join( thread1, NULL);
     pthread_join( thread2, NULL);

     cout << "Thread 1 returns: " <<  iret1 << endl;
     cout << "Thread 2 returns: " << iret2 << endl;

    return 0;
    }
void *print_message_function( void *ptr )
{
     cout << endl <<  ptr << endl;
     //return 0;
}

是否有办法将string作为(void *)参数传递?或者只有C style strings可以用作多线程参数-如链接中的参考代码所示。

参数需要是一个指针,你尝试传递一个对象给它。

您有两种选择,要么传递指向std::string对象的指针,要么传递指向底层字符串的指针。我推荐第一个:

 iret1 = pthread_create(&thread1, NULL, print_message_function, &message1);
然后你必须修改线程函数,否则它将打印指针,而不是它指向的字符串:
void* print_message_function(void* ptr)
{
    std::string str = *reinterpret_cast<std::string*>(ptr);
    std::cout << str << std::endl;
    return nullptr;
}

除非必须使用POSIX线程,否则我实际上宁愿推荐c++标准库中的线程功能:

#include <iostream>
#include <string>
#include <thread>
void print_message_function(const std::string& msg);
int main()
{
    std::string message1 = "Thread 1";
    std::string message2 = "Thread 2";
    std::thread thread1(print_message_function, std::cref(message1));
    std::thread thread2(print_message_function, std::cref(message2));
    thread1.join();
    thread2.join();
}
void print_message_function(const std:string& msg)
{
    std::cout << msg << std::endl;
}

通过将所有参数包装成简单的结构,可以将任何参数传递给pthread_create方法。例如:

struct ThreadParams {
    std::vector<int> ints;
    std::string clientName;
    // more params
};

你所需要做的就是在调用CreateThread函数之前初始化这个结构,然后传递一个指针:

ThreadParams * params = new ThreadParams();
params.setParameters();
pthread_create(..., params);
void* print_message_function(void* arg)
    ThreadParams * params = reinterpret_cast<ThreadParams *>(arg);
    // delete after usage;
    delete params;
}

调用pthread_create:

时需要获取字符串对象的地址(内存位置)
iret1 = pthread_create( &thread1, NULL, print_message_function, (void*)&message1);

你需要把你的内存void*转换回字符串指针,当你打印它(你不能写一个void*到流,流将不知道怎么处理它),解引用它:

cout << endl <<  *(string*)ptr << endl;

这应该可以工作,但是为了完全正确,你可能应该在转换到void*和从void*转换时使用reinterpret_cast。

最新更新