2017-11-09 4 views
0

私は1つのファイル(launch.cpp)から多くのスレッドを起動し、別のファイル(write.h)で定義されたスレッドセーフな関数を使用してコンソールに文字列を出力するプログラムを書いています。 、write.cpp)。多くのスレッドの起動 - インスタンシエーションエラー(C++)

私は関数がwrite.cppで正しく定義されていると信じていますが、私はlaunch.cppでスレッドを正しく作成しているとは思いません...作成しようとするスレッドごとにEclipseはインスタンス化エラーを投げます。

以下は私のコードと、launch.cppでスローされているエラーです。

write.cpp

#include <string> 
#include <sstream> 
#include <iostream> 
#include <thread> 
#include <mutex> 

#include "write.h" 

using namespace std; 

//Mutex (only one print executes at a time) 
mutex m; 

//Threadsafe print functions 
void PRINT1(std::string &txt) { 
    m.lock(); 
    cout<<txt<<endl;  
    m.unlock(); 
} 
void PRINT2(std::string &txt, std::string &txt1) { 
    m.lock(); 
    cout<<txt<<txt1<<endl; 
    m.unlock(); 
} 
void PRINT3(std::string &txt, std::string &txt1, std::string &txt2) { 
    m.lock(); 
    cout<<txt<<txt1<<txt2<<endl;  
    m.unlock(); 
} 
void PRINT4(std::string &txt, std::string &txt1, std::string &txt2, std::string &txt3) { 
    m.lock(); 
    cout<<txt<<txt1<<txt2<<txt3<<endl; 
    m.unlock(); 
} 

void PRINT5(std::string &txt, std::string &txt1, std::string &txt2, std::string &txt3, std::string &txt4) { 
    m.lock(); 
    cout<<txt<<txt1<<txt2<<txt3<<txt4<<endl;  
    m.unlock(); 
} 

launch.cpp

#include <string> 
#include <sstream> 
#include <iostream> 
#include <thread> 
#include <mutex> 

#include "write.h" 

using namespace std; 

const string txt = "Txt"; 
const string txt1 = "Txt1"; 
const string txt2 = "Txt2"; 
const string txt3 = "Txt3"; 
const string txt4 = "Txt4"; 

int main() { 

    //Constructs threads and runs 
    thread t1(PRINT1, txt); 

    thread t2(PRINT2, txt, txt1); 

    thread t3(PRINT3, txt, txt1, txt2); 

    thread t4(PRINT4, txt, txt1, txt2, txt3); 

    thread t5(PRINT5, txt, txt1, txt2, txt3, txt4); 

    //Makes the main thread wait for the new threads to finish   
    t1.join(); 
    t2.join(); 
    t3.join(); 
    t4.join(); 
    t5.join(); 

    return 0; 
} 

エラー

Error

+0

const文字列以外の文字列への参照を期待する関数に 'const string'オブジェクトを渡そうとしています。スレッドを忘れてしまいます。ただ 'PRINT1(txt)'はコンパイルされません。 –

+0

@IgorTandetnik良いキャッチ、私はそれを修正し、すべてが今コンパイル中です...しかし、私はまだ印刷機能への呼び出しでスレッドを作成しようとすると同じインスタンス化のエラーに直面しています。 – tang

答えて

1

は、2つの問題がここに遊びにあります。

1)txt変数はconstと宣言されているため、非const参照はそれらにバインドできません。
2)std::threadは、引数を内部ストレージにコピー(または移動)し、そのコピーをスレッド関数にrvaluesとして渡します。非const左辺値参照は右辺値にバインドできません。

、この作業を行うには、あなたがあなたのtxt変数非constを作成し、std::reference_wrapperstd::threadさんへのコンストラクタ渡すのいずれかが必要です。

void PRINT1(std::string& txt) { 
    std::cout << txt << '\n';  
} 

std::string txt = "Txt"; 

int main() { 
    std::thread t1(PRINT1, std::ref(txt)); 
    t1.join(); 
} 

Live Demo

それともstd::threadは、コピーを作成してみましょうし、そして

void PRINT1(const std::string& txt) { 
    std::cout << txt << '\n';  
} 

const std::string txt = "Txt"; 

int main() { 
    std::thread t1(PRINT1, txt); 
    t1.join(); 
} 
const左端参照または右端参照のいずれかを受け入れます。

Live demo

どのオプションを選択するかは、元の文字列を変更するスレッドが必要かどうかによって異なります。この場合、すべてのスレッドが実行しているので、文字列を出力しているので、2番目のオプションをお勧めします。同時実行性の問題を減らすためですが、実際のプログラムの必要性に応じて選択する必要があります。

関連する問題