我正在编写一个程序,它从一个文件(launch.cpp)启动许多线程,然后使用另一个文件(write.h,write.cpp)中定义的线程安全函数将字符串输出到控制台。
我相信我的函数在write.cpp中正确定义,但我不认为我在launch.cpp中正确创建了线程...对于我尝试创建的每个线程,Eclipse都会抛出一个实例化错误。 / p>
下面是我的代码,以及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;
}
错误
答案 0 :(得分:1)
这里有两个问题。
1)您的txt
变量被声明为const
,因此非const引用无法绑定到它们。
2)std::thread
将其参数复制(或移动)到某个内部存储中,并将这些副本作为rvalues传递给线程函数,而非const左值引用不能绑定到rvalue。
要完成这项工作,您需要将txt
变量设为非常量,并将std::reference_wrapper
传递给std::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();
}
或者让std::thread
制作副本,并在const
函数中接受PRINT
左值引用或右值引用:
void PRINT1(const std::string& txt) {
std::cout << txt << '\n';
}
const std::string txt = "Txt";
int main() {
std::thread t1(PRINT1, txt);
t1.join();
}
您选择哪个选项取决于您是否需要线程来修改原始字符串。在这种情况下,由于你所有的线程都在打印字符串,我建议第二个选项,因为它减少了可能的并发问题,但你选择的应该取决于你的实际程序的需要。