C++ 多线程 : terminate after throwing an instance of 'std::length_error'

标签 c++ multithreading pointers pthreads

我正在 Tutorials Point 上使用 pthread 在 C++ 中学习多线程(它可能很旧,但我只需要一些东西来开始)。我稍微修改了代码:

#include <pthread.h>
#include <iostream>
#include <string>

#define NUM_THREADS 5
#define DEBUG
#undef DEBUG

using namespace std;

struct thread_data {
    int thread_id = 0;
    string message = "";
};

void *printHello(void *threadData)
{
    struct thread_data* data = (struct thread_data*)threadData;
    int thread_id = data->thread_id;
    string message = data->message;

    cout << "From thread " << thread_id << ": " << message << "\n";
    pthread_exit(NULL);
}

int main(int argc, char** argv)
{
    pthread_t threads[NUM_THREADS];

    for (int i = 0; i < NUM_THREADS; i++) {
        struct thread_data* data = new thread_data();
        string message = "Special message for thread #" + to_string(i) + "!";

        #ifdef DEBUG
        cout << "DEBUG: " << "i = " << i << endl;
        #endif

        data->thread_id = i;
        data->message = message;

        cout << "main(): creating thread, " << i << endl;
        int rc = 0;
        rc = pthread_create(&threads[i], NULL, printHello, (void *) data);

        delete data;

        if (rc) {
            cout << "Error: unable to create thread: " << rc << "\n";
            return -1;
        }
    }

    pthread_exit(NULL);    
}

我编译了:

g++ -pthread -g -Wall -std=c++11 main.cpp -o main

输出是:

main(): creating thread, 0
main(): creating thread, 1
From thread 1: Special message for thread #1!
main(): creating thread, 2
From thread 2: Special message for thread #2!
main(): creating thread, 3
From thread 3: Special message for thread #3!
main(): creating thread, 4
From thread 4: Special message for thread #4!
terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_S_create
Aborted (core dumped)

如果我不使用 pthread_create 创建线程并直接调用 printHello 函数,则不会发生错误。有时,程序反而会抛出段错误,有时却运行得很顺利!

另一个问题是,从一开始就应该有一行说From thread 0: Special message for thread #0!,但是没有。

此外,有时会出现消息“线程#n 的特殊消息!”甚至根本没有出现。

我尝试在第 31 行初始化结构变量,使用静态分配的内存(堆栈而不是堆,不使用 new)。我尝试避免在 printHello 函数中使用指针,但自从上次pthread_create 的参数只接受指向函数参数的指针,我不能那样做。

我首先怀疑是赋值data->message = message时有问题,所以我尝试将字符串直接赋值给data->message,但是没有运气。但我仍然认为错误必须存在,因为异常是 std::length_error,由“basic_string”抛出。

或者,也许当我将 data 传递给 pthread_create 时,或者当我在第 18 行进行转换时,我做错了什么。我的想法是,当我将它传递给函数时,我将它作为指针传递,将其转换为空指针 void *。当 printHello 收到参数时,我将其转换为 thread_data* 类型,这是一个指针,这是它原来的样子。

那是我到目前为止能够想出的时间。如果我的文章中有什么晦涩的地方请评论(英语不是我的母语)。

提前谢谢大家。

最佳答案

您将在创建线程后立即删除 data。这意味着无法保证 data 指针在线程尝试访问它时仍指向事件对象。

您应该只在没有人打算再使用该对象时才删除data。例如。线程完成后(您可以使用 pthread_join 来实现,例如)。

关于C++ 多线程 : terminate after throwing an instance of 'std::length_error' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38262948/

相关文章:

c++ - 在这个位移操作中做了什么?

swift - 更新从后台线程更改 UI 的变量 - SWIFTUI

c - 将 char 指针复制到 char 指针数组时发生段错误

c - 用指针访问零位

c - 为什么要声明一个数组类型的参数?

c++ - 为什么 if 语句不起作用

c++ - 无法弄清楚为什么我的 IF 语句在使用 C++ 的 SQL 中被跳过

c++ - 调用drawow会导致堆损坏

java - 暂停执行 main 方法中的循环,直到所有线程完成 Java 1.5

multithreading - Haskell:并行代码比顺序版本慢