多线程程序中的核心转储:basic_string :: _ S_construct null无效
问题描述:
我希望4个线程将进入名为read
的同一个函数,并执行函数中的内容(在监视器上打印之后进行读取,以及以显示所有...)。 问题:多线程程序中的核心转储:basic_string :: _ S_construct null无效
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
trAborted (core dumped)
的代码是:
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <time.h>
#include <cstdlib>
#include <fstream>
#include <string>
using namespace std;
struct v {
int id;
char* ad;
v(int a, char* t) {
id = a;
ad = t;
}
};
int bank = 1000;
pthread_mutex_t mutex;
void* read(void* argument)
{
cout << "tr";
v* d;
int num;
d = (v*) argument;
string l = d->ad;
int n = d->id;
string x = "";
ifstream textfile;
textfile.open(l.c_str());
while (!textfile.eof()) {
textfile >> x;
if (x == "SUB") {
pthread_mutex_lock(&mutex);
textfile >> num;
bank = bank - num;
cout << "person num " << n << " sub " << num << " dollars and know in the Bank: " << bank << endl;
pthread_mutex_unlock(&mutex);
}
if (x == "ADD") {
pthread_mutex_lock(&mutex);
textfile >> num;
bank = bank + num;
cout << "person num " << n << " add " << num << " dollars and know in the Bank: " << bank << endl;
pthread_mutex_unlock(&mutex);
}
if (x == "GET") {
pthread_mutex_lock(&mutex);
cout << "person num " << n << " look in the Bank: " << bank << endl;
pthread_mutex_unlock(&mutex);
}
}
textfile.close();
return 0;
}
int main(void)
{
pthread_mutex_init(&mutex, NULL);
int i = 0, j = 0;
v data1(1, "file1.dat"), data2(2, "file2.dat"), data3(3, "file3.dat"), data4(4, "file4.dat");
pthread_t t1, t2, t3, t4;
i = pthread_create(&t1, NULL, read, (void*)&data1);
if (i != 0) cout << "error" ;
j = pthread_create(&t2, NULL, read, (void*)&data2);
if (j != 0) cout << "error" ;
i = pthread_create(&t3, NULL, read, (void*)&data3);
if (i != 0) cout << "error" ;
j = pthread_create(&t4, NULL, read, (void*)&data4);
if (j != 0) cout << "error" ;
pthread_exit(NULL);
return 0;
}
答
你传递栈,这是几乎从来没有一个好主意,你的线程的数据。
当您调用pthread_exit
时,主线程的堆栈(包含dataN
对象)被释放。如果其中一个线程在pthread_exit
之后安排,它将在解除分配的对象上运行。
最好的解决方案是通过new
在堆上分配您的data
对象。
+0
更好的是:在调用'pthread_exit()'之前,在每个子线程上调用'pthread_join()'。 – 2013-05-03 19:34:44
通过用try/catch连续包装程序中越来越小的部分来做分而治之,直到找出哪个语句正在抛出。另外:什么操作系统,编译器,编译器的版本号,也许最重要的是libc的版本?它可能不是答案,但在一些较旧的Gnu libcs中,字符串构造函数不是线程安全的(它们在实现中深处共享一个未同步的单例)。 – 2013-05-03 15:03:00
请不要在核心转储错误之前发布问题,直到您告诉我们错误的行号。你真的希望我们为你编译和调试吗?告诉我们哪一行是问题。 (如果你不知道该怎么做,那么在编写超过10行的程序之前,请学会使用gdb,运行“gdb ./myprog”,并在使用堆栈跟踪调用终止时停止。) – 2013-05-03 17:00:41
@NicholasWilson:我同意(我们需要行号),但这是一个未捕获的异常,所以在终止时堆栈已经完全解除。那么gdb会给出任何有用的信息?这就是为什么我提出了分而治之的尝试捕捉方法。 – 2013-05-03 17:48:38