使用pthread和多线程编程的c中的Segfault



嗨,这是我试图编写的多线程程序,但它给了我segfault
原始代码在没有多线程的情况下运行良好,但这给了我segfault
我在每次全局var读取中都使用了互斥锁,但即使是一个线程也给了我segfault

# include <stdio.h> 
# include <string.h> 
# include <pthread.h>
# include <stdlib.h>
# include <math.h>
# include <limits.h>
# define NUMBER_OF_COLUMNS 20
# define NUMBER_OF_CLASSES 4
# define NUMBER_OF_THREADS 4
# define NUMBER_OF_COLUMNS_PLUS_ONE 21 //STUPID C WONT LET ME MAKE GLOBAL VECTORS
double max[NUMBER_OF_COLUMNS], min[NUMBER_OF_COLUMNS];
double maxMinusMin[NUMBER_OF_COLUMNS];
int number_of_datas = 0, number_of_wrong_predictions = 0;
pthread_t threads[NUMBER_OF_THREADS];
pthread_mutex_t mutex_minmax;

void * solve(void *id){
FILE *traincsv, *weightscsv;
long tid;
tid = (long) id;
char buffer[1024];
char* token;
int EOFchecker = 1;
double temp;
double sum[NUMBER_OF_CLASSES];
double vectors[NUMBER_OF_CLASSES][NUMBER_OF_COLUMNS_PLUS_ONE];
int winner = 0;
int number_of_datas_local = 0, number_of_wrong_predictions_local = 0;
char filename[16];
sprintf(filename, "trainq%ld.csv", (tid + 1));
printf("Hello World! Thread ID, %ldn", tid);
printf("%sn", filename);
traincsv = fopen(filename,"r");
weightscsv = fopen("weights.csv","r");

//load vectors to array last one is bias
pthread_mutex_lock(&mutex_minmax);
fscanf(weightscsv,"%s",buffer);//first junk line
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
fscanf(weightscsv,"%s",buffer);
token = strtok(buffer,",");
for (size_t j = 0; j < NUMBER_OF_COLUMNS + 1; j++)
{
temp = atof(token);
vectors[i][j] = temp;
token = strtok(NULL,",");//next token of last string
}
}
pthread_mutex_unlock(&mutex_minmax);
pthread_mutex_lock(&mutex_minmax);
fscanf(traincsv,"%s",buffer);//first line is just names
fscanf(traincsv,"%s",buffer);
pthread_mutex_unlock(&mutex_minmax);
while (EOFchecker != EOF)
{
token = strtok(buffer,",");
//reset sum of wieghts to bias;
printf("thread id %ld token %sn",tid,token);
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
sum[i] = vectors[i][NUMBER_OF_COLUMNS];
}
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
temp = atof(token);
//Normalize
pthread_mutex_lock(&mutex_minmax);
temp = (temp-min[i])/(maxMinusMin[i]);
pthread_mutex_unlock(&mutex_minmax);
for (size_t j = 0; j < NUMBER_OF_CLASSES; j++)
{
sum[j] += vectors[j][i] * temp;
}
token = strtok(NULL,",");//next token of last string
}
//check which vector has most points
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
if (sum[i] > sum[winner])
{
winner = i;
}

}
if(winner != atof(token)){
number_of_wrong_predictions_local ++;
}
number_of_datas_local ++;
pthread_mutex_lock(&mutex_minmax);
EOFchecker = fscanf(traincsv,"%s",buffer);
pthread_mutex_unlock(&mutex_minmax);
}
pthread_mutex_lock(&mutex_minmax);
number_of_datas+=number_of_datas_local;
number_of_wrong_predictions+=number_of_wrong_predictions_local;
pthread_mutex_unlock(&mutex_minmax);
pthread_exit(NULL);
}
int main(){
void * status;
FILE *traincsv, *traincsvnorm, *weightscsv;
char buffer[1024];
char* token;
double temp;
int EOFchecker = 1;
int return_code;


if (pthread_mutex_init(&mutex_minmax, NULL) != 0) { 
printf("n mutex init has failedn"); 
return 1; 
} 

for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
min[i] = INFINITY;
}


traincsv = fopen("train.csv","r");
traincsvnorm = fopen("trainnorm.csv","w+");
// find min and max
fscanf(traincsv,"%s",buffer);//first line is just names
fscanf(traincsv,"%s",buffer);
while (EOFchecker != EOF)
{
token = strtok(buffer,",");
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
temp = atof(token);
if(max[i]<temp) max[i] = temp;
if(min[i]>temp) min[i] = temp;
token = strtok(NULL,",");//next token of last string
}
EOFchecker = fscanf(traincsv,"%s",buffer);
}
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
maxMinusMin[i] = max[i] - min[i];
}
for(long tid = 0; tid < NUMBER_OF_THREADS; tid++)
{
return_code = pthread_create(&threads[tid],
NULL, solve, (void *) tid);
if (return_code)
{
printf("ERROR; return code from pthread_create() is %dn",
return_code);
exit(-1);
}
}
// pthread_mutex_destroy(&mutex_minmax);
printf("wrong predictions : %d nall predictions : %d n",number_of_wrong_predictions,number_of_datas);
for(long i = 0; i < NUMBER_OF_THREADS; i++)
pthread_join(threads[i], &status);
fclose(traincsv);
fclose(traincsvnorm);
pthread_exit(NULL);
}

这是我的原始代码,运行良好

# include <stdio.h> 
# include <string.h> 
# include <pthread.h>
# include <stdlib.h>
# include <math.h>
# define NUMBER_OF_COLUMNS 20
# define NUMBER_OF_CLASSES 4
// void * solve(void *id){
//     int tid;
//     tid = (int) id;
// }
int main(){
FILE *traincsv, *traincsvnorm, *weightscsv;
char buffer[1024];
char* token;
double temp, max[NUMBER_OF_COLUMNS], min[NUMBER_OF_COLUMNS];
int EOFchecker = 1;
int number_of_datas = 0, number_of_wrong_predictions = 0;
double vectors[NUMBER_OF_CLASSES][NUMBER_OF_COLUMNS + 1];
double sum[NUMBER_OF_CLASSES];
int winner = 0;
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
min[i] = INFINITY;
}


traincsv = fopen("train.csv","r");
traincsvnorm = fopen("trainnorm.csv","w+");
weightscsv = fopen("weights.csv","r");
// fprintf(traincsvnorm,"%sn",buffer);
//load vectors to array last one is bias
fscanf(weightscsv,"%s",buffer);//first junk line
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
fscanf(weightscsv,"%s",buffer);
token = strtok(buffer,",");
for (size_t j = 0; j < NUMBER_OF_COLUMNS + 1; j++)
{
temp = atof(token);
vectors[i][j] = temp;
token = strtok(NULL,",");//next token of last string
}
}
//find min and max
fscanf(traincsv,"%s",buffer);//first line is just names
fscanf(traincsv,"%s",buffer);
while (EOFchecker != EOF)
{
token = strtok(buffer,",");
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
temp = atof(token);
if(max[i]<temp) max[i] = temp;
if(min[i]>temp) min[i] = temp;
token = strtok(NULL,",");//next token of last string
}
EOFchecker = fscanf(traincsv,"%s",buffer);
}
// Normilize
double maxMinusMin[NUMBER_OF_COLUMNS];
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
maxMinusMin[i] = max[i] - min[i];
}
EOFchecker = 1;
fseek(traincsv,0,SEEK_SET);
fscanf(traincsv,"%s",buffer);//first line is just names
fscanf(traincsv,"%s",buffer);
while (EOFchecker != EOF)
{
token = strtok(buffer,",");
//reset sum of wieghts to bias;
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
sum[i] = vectors[i][NUMBER_OF_COLUMNS];
}
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
temp = atof(token);
temp = (temp-min[i])/(maxMinusMin[i]);
for (size_t j = 0; j < NUMBER_OF_CLASSES; j++)
{
sum[j] += vectors[j][i] * temp;
}
token = strtok(NULL,",");//next token of last string
}
//check which vector has most points
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
if (sum[i] > sum[winner])
{
winner = i;
}

}
if(winner != atof(token)){
number_of_wrong_predictions ++;
}
number_of_datas ++;
EOFchecker = fscanf(traincsv,"%s",buffer);
}
printf("wrong predictions : %d nall predictions : %d n",number_of_wrong_predictions,number_of_datas);
fclose(traincsv);
fclose(traincsvnorm);
fclose(weightscsv);
}

这些是输入train.csv weights.csv
它有时会给我free((:无效指针错误,这里还有gdb bt

找到了它strtok不是可重入的,所以它是线程不安全的。在POSIX环境中,请改用strtok_r

最新更新