C ++多线程:抛出'std :: length_error'的实例后终止

时间:2016-07-08 09:12:07

标签: 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的特殊消息!”根本没有出现。

我尝试初始化struct的变量,在第31行使用静态分配的内存(不使用new的堆栈而不是堆)。我试图避免在printHello函数中使用指针,但是因为pthread_create的最后一个参数只接受指向函数参数的指针,我不能这样做。

我首先怀疑当我分配data->message = message时出现了问题,所以我尝试将字符串直接分配给data->message,但没有运气。但我仍然认为错误必须存在,因为异常是std::length_error,由'basic_string`引发。

或者,也许当我将data传递给pthread_create或者当我在第18行进行演员表时,我做错了什么。我的想法是,当我将它传递给函数时,我将它作为指针传递,将其转换为void指针void *。当printHello收到参数时,我将其强制转换为thread_data*类型,这是一个指针,就是它最初的位置。

到目前为止我能够提出这个问题。如果我的写作中有些含糊不清的东西(英语不是我的第一语言),请评论。

提前感谢大家。

1 个答案:

答案 0 :(得分:2)

您在创建主题后立即删除data。这意味着,当线程尝试访问时,data指针仍然无法保证指向活动对象。

只有当没人会再使用该对象时,您才应删除data。例如。线程完成后(你可以使用pthread_join来实现这一点。)。