2017-02-14 5 views
0

文字列型ベクトル要素をpthread_create()関数に渡そうとしています。メッセージは出力に印刷されません。どこが間違っていますか?pthread_create()にstring型のベクトル要素を引数として渡すにはどうすればよいですか?

#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; 

} 

出力:

がスレッドを実行

がスレッドを実行

がスレッドを実行

がスレッドを実行

実行中のスレッド= = = = =

+2

もしあなたがC++ 11にアクセスできるのであれば、 'std :: thread'を打つことをお勧めします。それは実際には型システムで動作します。これはもはや 'void * 'を意味しません。 – NathanOliver

+1

なぜCスタイルのコードをC++で書いていますか?なぜ定数にマクロを使用していますか?なぜ 'std :: thread'を使わないのですか? –

答えて

1

pthread_create()に引数として文字列型のベクトル要素を渡すにはどうすればよいですか?

正確にどのようにそれらを渡すか。

ただし、スレッドが生きている間に文字列が破棄されたり移動されたりしないように注意する必要があります。

メッセージが出力に印刷されません。

スレッドに渡す文字列はすべて空です。


私はあなたのベクトルがどのように機能するかについて混乱していると思われる:

vector<string> v(NUM_THREADS); 

これは、5つの要素のベクトルを構築します。それぞれの5文字列は空です。

v.push_back(s); 

これは、ベクター中に6日... 10日の要素を追加します。これらの文字列は空ではありませんが、空の文字列を含むインデックス0 ... 4を使用したため、スレッドに渡されません。

さらに、これらのプッシュバックによってベクトルが再割り当てされる可能性があります。その場合、先に作成されたスレッドに渡されたポインタは無効になり、結果として未定義の動作になります。

v[i] = s; 

別のアプローチは、空のベクターを開始することで、ループ内で生成された文字列をプッシュ:

あなたはおそらくでこれを置き換える必要があります。ただし、その場合は、再割り当てによるポインタの無効化を避けるために、メモリを事前に予約する必要があります。または、スレッドを開始する前に別のループでベクトルを埋めてください。


PS。 print_thread_detailsvoid*を返しますが、return文がありません。この動作は未定義です。

1

問題は、ベクタを空の文字列であらかじめ埋めているベクタコンストラクタを呼び出していることです。その後、空でない文字列をベクタの最後に追加しています。ベクトルは5ではなく10個の文字列で終わります。しかし、スレッドは空の文字列しか表示しません。

ベクターコンストラクタに渡す値を削除すると、ベクターは最初は空になります。実際に項目を追加することなく、ベクトルを事前に割り当てる代わりに、ベクトルのreserve()メソッドを呼び出します。そうでなければ

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

を、reserve()せず、push_back()への各呼び出しは、潜在的にどのだろう、既存の文字列ポインタを無効に、ベクトルの内部領域を再割り当てしますベクトルを生成して同時にスレッドを作成すると悪いことになります。 main()を終了させる前に、あなたがスレッドを開始すると、あなたは彼らが終了するのを待つ必要があり、

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]); 
    ... 
} 

サイドノートでは:より安全なアプローチは、スレッドを作成する前に、ベクター中にすべての文字列をプッシュすることですそれ以外の場合は、スレッドが文字列値を使用している間にベクターを破棄することができます。

関連する問題