如何从线程修改字符串?

时间:2017-03-09 23:15:12

标签: c++ multithreading

我试图从线程修改一些字符串(每个线程都有自己的字符串)但所有字符串都存储在一个向量中,因为我需要能够在线程完成它们之后访问它们。

我还没有在c ++中使用过线程,所以如果这是一件很糟糕的事情,欢迎提出所有建议:)

基本上,程序现在唯一能做的就是:

  • 创建一些主题
  • 向每个帖子发送一个字符串和一个id
  • 线程函数修改字符串以向其添加id

这给出了一个段错误:(

这只是一种糟糕的做法吗?我怎么能这样做?

static const int cores = 8;

void bmh_t(std::string & resr, int tid){
    resr.append(std::to_string(tid));
    resr.append(",");
    return;
}        

std::vector<std::string> parbmh(std::string text, std::string pat){

    std::vector<std::string> distlists;
    std::thread t[cores]; 
    //Launch a group of threads
    for (int i = 0; i < cores; ++i) {
        distlists.push_back(" ");
        t[i] = std::thread(bmh_t,std::ref(distlists[i]), i);
    }

    for (int i = 0; i < cores; ++i) {
        t[i].join();
    }

    return distlists;
}

2 个答案:

答案 0 :(得分:4)

你的基本方法很好。编写并行代码时需要考虑的主要问题是线程之间共享的任何数据都是以安全的方式完成的。因为您的算法为每个线程使用不同的字符串,所以它是一种很好的方法。

您看到崩溃的原因是,在您已经为每个线程提供对存储在向量中的数据的引用之后,您正在对字符串向量调用push_back。这是一个问题,因为当其大小达到其容量时,push_back需要增长向量。这种增长会使您分配给每个线程的引用无效,从而导致它们写入释放的内存。

修复非常简单:只需提前确定您的矢量不需要增长。这可以通过指定初始元素数的构造函数参数来完成;对reserve()的调用;或调用resize()。

这是一个不会崩溃的实现:

static const int cores = 8;

void bmh_t(std::string & resr, int tid){
    resr.append(std::to_string(tid));
    resr.append(",");
    return;
}

std::vector<std::string> parbmh(){

    std::vector<std::string> distlists;
    std::thread t[cores];
    distlists.reserve(cores);

    //Launch a group of threads
    for (int i = 0; i < cores; ++i) {
        distlists.push_back(" ");
        t[i] = std::thread(bmh_t, std::ref(distlists[i]), i);
    }

    for (int i = 0; i < cores; ++i) {
        t[i].join();
    }

    return distlists;
}

答案 1 :(得分:1)

在线程可以对包含的字符串进行操作之前,字符串向量正在被破坏。在返回之前,你想要join线程,这样字符串的矢量就不会被破坏。