【问题标题】:Launching Many Threads - Instantiation Error (C++)启动多个线程 - 实例化错误 (C++)
【发布时间】:2018-04-23 03:15:24
【问题描述】:

我正在编写一个程序,它从一个文件 (launch.cpp) 启动多个线程,然后使用另一个文件 (write.h、write.cpp) 中定义的线程安全函数将字符串输出到控制台。

我相信我的函数在 write.cpp 中定义正确,但我认为我在 launch.cpp 中没有正确创建线程...对于我尝试创建的每个线程,Eclipse 都会引发实例化错误。

以下是我的代码,以及在 launch.cpp 中引发的错误。

写.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;
}

错误

【问题讨论】:

  • 您正在尝试将 const string 对象传递给期望引用非常量字符串的函数。忘记线程 - 只是简单的 PRINT1(txt) 不会编译。
  • @IgorTandetnik 很好,我修复了这个问题,现在一切都在编译......但是当我尝试创建一个调用打印函数的线程时,我仍然面临同样的实例化错误。跨度>

标签: c++ eclipse multithreading c++11 mutex


【解决方案1】:

这里有两个问题。

1) 您的 txt 变量声明为 const,因此非常量引用无法绑定到它们。
2) std::thread 将其参数复制(或移动)到某个内部存储中,并将这些副本作为右值传递给线程函数,并且非常量左值引用不能绑定到右值。

要完成这项工作,您需要将 txt 变量设为非 const 并将 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();
}

Live Demo

或者让std::thread 进行复制,并在您的PRINT 函数中接受const 左值引用或右值引用:

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

您选择哪个选项取决于您是否需要线程来修改原始字符串。在这种情况下,由于您的所有线程都在打印字符串,因此我建议您使用第二个选项,因为它可以减少可能的并发问题,但您应该根据实际程序的需要来选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    相关资源
    最近更新 更多