简体   繁体   中英

Launching Many Threads - Instantiation Error (C++)

I am writing a program that launches many threads from one file (launch.cpp), and then outputs strings to the console using thread-safe functions defined in another file (write.h, write.cpp).

I believe that my functions are defined correctly in write.cpp, but I do not think I am creating the threads correctly in launch.cpp... For every thread that I try to create, Eclipse throws an instantiation error.

Below is my code, along with the errors that are being thrown in 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

错误

There are two issues at play here.

1) Your txt variables are declared const , so a non-const reference cannot bind to them.
2) std::thread copies (or moves) its arguments into some internal storage and passes those copies to the thread function as rvalues, and a non-const lvalue reference cannot bind to an rvalue.

To make this work, you need to either make your txt variables non-const and pass a std::reference_wrapper to std::thread 's constructor:

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

Or let std::thread make a copy, and accept either a const lvalue reference or an rvalue reference in your PRINT functions:

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

const std::string txt = "Txt";

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

Live demo

Which option you choose depends on if you need the thread to modify the original string or not. In this case, since all your threads are doing is printing the strings I would recommend the second option, since it reduces possible concurrency issues, but which you choose should depend on the needs of your actual program.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM