如何将string类型的vector元素作为参数传递给pthread_create()?

时间:2017-02-14 16:41:21

标签: c++ pthreads

我正在尝试将字符串类型向量元素传递给pthread_create()函数。消息未在输出中打印。我哪里错了?

#include <iostream>
#include <pthread.h>
#include <cstdlib>
#include <vector>

using namespace std;

#define NUM_THREADS 5

void *print_thread_details(void  *thread_no){

    std::string str = *reinterpret_cast<std::string*>(thread_no);
    cout<<"\n Running thread = "<<str<<endl;
    pthread_exit(NULL);

}

int main(){

/*initialize an array of pthreads*/

    pthread_t threads[NUM_THREADS];
    int rc;

    vector<string> v(NUM_THREADS);
    for(int i=0;i<NUM_THREADS;i++){
        string s = "Thread No = ";
        char temp = i+'0';
        s=s+temp;
        v.push_back(s);

        rc = pthread_create(&threads[i], NULL, print_thread_details,&v[i] );

        if (rc){
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }
    }

 pthread_exit(NULL);
return 0;

}

输出:

正在运行thread =

正在运行thread =

正在运行thread =

正在运行thread =

正在运行thread =

2 个答案:

答案 0 :(得分:1)

  

如何将string类型的vector元素作为参数传递给pthread_create()?

你现在正是如何传递它们的。

但是,在线程处于活动状态时,必须注意防止字符串被销毁或移动。

  

消息未在输出中打印。

传递给线程的所有字符串都是空的。

我怀疑你对矢量的工作方式感到困惑:

vector<string> v(NUM_THREADS);

这构造了5个元素的向量。 5个字符串中的每一个都是空的。

v.push_back(s);

这会在向量中添加第6个〜第10个元素。这些字符串不为空,但也不会传递给线程,因为您使用的索引0 ... 4包含空字符串。

此外,这些回退可能会导致向量重新分配,在这种情况下,传递给先前创建的线程的指针将变为无效,从而导致未定义的行为。

您应该将其替换为:

 v[i] = s;

另一种方法是从空向量开始,并在循环中推送生成的字符串。但在这种情况下,您必须预先保留内存以避免由于重新分配而导致指针失效。或者在启动任何线程之前,在单独的循环中填充向量。

PS。 print_thread_details返回void*但缺少return语句。行为未定义。

答案 1 :(得分:1)

问题是你正在调用使用空字符串预填充向量的向量构造函数,然后你将其他非空字符串推送到向量的末尾。向量最终会有10个字符串,而不是5个。但是线程只能看到空字符串。

删除传递给向量构造函数的值,然后向量最初将为空。调用向量的reserve()方法来预先分配向量而不实际向其添加项目:

vector<string> v;
v.reserve(NUM_THREADS);

否则,在没有reserve()的情况下,每次调用push_back()都可能会重新分配向量的内部区域,使任何现有的字符串指针无效,这在填充向量并创建线程时会很糟糕。同时。更安全的方法是在创建线程之前将所有字符串推入向量:

vector<string> v;

for(int i=0;i<NUM_THREADS;i++){
    // consider using std::ostringstream instead...
    string s = "Thread No = ";
    char temp = i+'0';
    s=s+temp;
    v.push_back(s);
}

for(int i=0;i<NUM_THREADS;i++){
    rc = pthread_create(&threads[i], NULL, print_thread_details,&v[i] );
    ...
}

在旁注中,一旦启动线程,您需要等待它们终止,然后才允许main()退出,否则在线程仍在使用字符串值时可以销毁该向量。