C++ 多线程:抛出 'std::length_error' 的实例后终止
C++ multithreading: terminate after throwing an instance of 'std::length_error'
我正在 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!
,但是没有
此外,有时消息 "Special message for thread #n!" 甚至根本没有出现。
我尝试在第 31 行初始化结构的变量,使用静态分配的内存(堆栈而不是堆,不使用 new
)。我尝试避免在 printHello 函数中使用指针,但自从最后一个参数of pthread_create 只接受指向函数参数的指针,我不能那样做。
我的第一个怀疑是我赋值data->message = message
时有问题,所以我尝试将字符串直接赋值给data->message
,但没有成功。但我仍然认为错误必须存在,因为异常是 std::length_error
,由 'basic_string` 抛出。
或者,也许当我将 data
传递给 pthread_create
或当我在第 18 行进行转换时,我做错了什么。我的想法是,当我将它传递给函数时,我将它作为指针传递,将其转换为 void 指针 void *
。当printHello
接收到参数时,我将其转换为类型thread_data*
,这是一个指针,它本来就是这样。
那是我到目前为止能够想出的时间。如果我的文章中有什么晦涩的地方请评论(英语不是我的母语)。
先谢谢大家了。
您将在创建话题后立即删除 data
。这意味着无法保证 data
指针在线程尝试访问它时仍指向活动对象。
您应该只在没有人打算再使用该对象时才删除 data
。例如。线程完成后(您可以使用 pthread_join
来实现,例如)。
我正在 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!
,但是没有
此外,有时消息 "Special message for thread #n!" 甚至根本没有出现。
我尝试在第 31 行初始化结构的变量,使用静态分配的内存(堆栈而不是堆,不使用 new
)。我尝试避免在 printHello 函数中使用指针,但自从最后一个参数of pthread_create 只接受指向函数参数的指针,我不能那样做。
我的第一个怀疑是我赋值data->message = message
时有问题,所以我尝试将字符串直接赋值给data->message
,但没有成功。但我仍然认为错误必须存在,因为异常是 std::length_error
,由 'basic_string` 抛出。
或者,也许当我将 data
传递给 pthread_create
或当我在第 18 行进行转换时,我做错了什么。我的想法是,当我将它传递给函数时,我将它作为指针传递,将其转换为 void 指针 void *
。当printHello
接收到参数时,我将其转换为类型thread_data*
,这是一个指针,它本来就是这样。
那是我到目前为止能够想出的时间。如果我的文章中有什么晦涩的地方请评论(英语不是我的母语)。
先谢谢大家了。
您将在创建话题后立即删除 data
。这意味着无法保证 data
指针在线程尝试访问它时仍指向活动对象。
您应该只在没有人打算再使用该对象时才删除 data
。例如。线程完成后(您可以使用 pthread_join
来实现,例如)。