如何修复 pthread_create 调用中的分段错误
How to fix a Segmentation Fault in pthread_create call
我的当前代码有问题。我正在做一个项目,我正在使用线程从终端读取一组文件,并告诉文件的单个和总分组中有多少行。我的问题是,当我 运行 代码时,我得到一个核心转储,当我 运行 我的代码通过 gdb 时,我在 pthread_create 调用时遇到分段错误。是因为我的实现还是因为我的代码中的其他原因?
#define NUM_THREADS 12
struct thread_data{
char *thread_id;
int count;
};
struct thread_data thread_data_array[NUM_THREADS];
void* filecount(void * thread_arg){
char thread_id;
int count;
struct thread_data *thread;
thread = (struct thread_data *) thread_arg;
thread_id = *thread->thread_id;
count = thread->count;
FILE *fp = fopen(&thread_id, "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open %s\n", thread_id);
exit(-1);
}
for (char c = getc(fp); c != EOF; c = getc(fp))
if (c == '\n')
count++;
fclose(fp);
pthread_exit(NULL);
}
int main(int argc, char *argv[]){
if (argc == 1)
return 0;
pthread_t threads[argc];
int t, total_count, count;
total_count = 0;
for(t=1; t<argc; t++){
thread_data_array[t].thread_id = argv[t];
thread_data_array[t].count = count;
printf("Creating thread for file: %s",thread_data_array[t].thread_id);
///This is the line in question///
pthread_create(&threads[t], NULL,filecount,(void *) &thread_data_array[t]);
printf("File name: %s --- line count: %d", thread_data_array[t].thread_id, total_count);
total_count += thread_data_array[t].count;
}
printf("Total line count: %d", total_count);
pthread_exit(NULL);
}
总结一些评论:
这个
char thread_id;
thread_id = *thread->thread_id;
会给你文件名的第一个字符。因此,虽然 &thread_id
是 fopen
的第一个参数的正确类型 (char *
),但它不是指向空终止字符串的指针。这是 undefined behaviour.
在
thread_data_array[t].count = count;
count
未初始化,其值不确定。这是 undefined behaviour.
在使用其结果之前,您需要等待每个线程完成。 pthread_join
是这里要使用的函数。
getc
(fgetc
) returns 输入 int
,这允许检查 EOF
。缩小到 char
会移除正确测试 EOF
.
的能力
thread_data_array
应该匹配 threads
数组的大小。
这是一个重构的程序:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct thread_data {
char *thread_id;
int count;
};
void *filecount(void *thread_arg){
struct thread_data *arg = thread_arg;
FILE *fp = fopen(arg->thread_id, "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open %s\n", arg->thread_id);
pthread_exit(NULL);
}
for (int c = getc(fp); c != EOF; c = getc(fp))
if (c == '\n')
arg->count++;
fclose(fp);
return NULL;
}
int main(int argc, char *argv[]){
if (argc == 1)
return 0;
argv++;
argc--;
pthread_t threads[argc];
struct thread_data thread_data_array[argc];
int total_count = 0;
for (int i = 0; i < argc; i++) {
thread_data_array[i].thread_id = argv[i];
thread_data_array[i].count = 0;
pthread_create(&threads[i], NULL, filecount,(void *) &thread_data_array[i]);
}
for (int i = 0; i < argc; i++) {
pthread_join(threads[i], NULL);
total_count += thread_data_array[i].count;
}
printf("Total line count: %d\n", total_count);
}
我的当前代码有问题。我正在做一个项目,我正在使用线程从终端读取一组文件,并告诉文件的单个和总分组中有多少行。我的问题是,当我 运行 代码时,我得到一个核心转储,当我 运行 我的代码通过 gdb 时,我在 pthread_create 调用时遇到分段错误。是因为我的实现还是因为我的代码中的其他原因?
#define NUM_THREADS 12
struct thread_data{
char *thread_id;
int count;
};
struct thread_data thread_data_array[NUM_THREADS];
void* filecount(void * thread_arg){
char thread_id;
int count;
struct thread_data *thread;
thread = (struct thread_data *) thread_arg;
thread_id = *thread->thread_id;
count = thread->count;
FILE *fp = fopen(&thread_id, "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open %s\n", thread_id);
exit(-1);
}
for (char c = getc(fp); c != EOF; c = getc(fp))
if (c == '\n')
count++;
fclose(fp);
pthread_exit(NULL);
}
int main(int argc, char *argv[]){
if (argc == 1)
return 0;
pthread_t threads[argc];
int t, total_count, count;
total_count = 0;
for(t=1; t<argc; t++){
thread_data_array[t].thread_id = argv[t];
thread_data_array[t].count = count;
printf("Creating thread for file: %s",thread_data_array[t].thread_id);
///This is the line in question///
pthread_create(&threads[t], NULL,filecount,(void *) &thread_data_array[t]);
printf("File name: %s --- line count: %d", thread_data_array[t].thread_id, total_count);
total_count += thread_data_array[t].count;
}
printf("Total line count: %d", total_count);
pthread_exit(NULL);
}
总结一些评论:
这个
char thread_id;
thread_id = *thread->thread_id;
会给你文件名的第一个字符。因此,虽然 &thread_id
是 fopen
的第一个参数的正确类型 (char *
),但它不是指向空终止字符串的指针。这是 undefined behaviour.
在
thread_data_array[t].count = count;
count
未初始化,其值不确定。这是 undefined behaviour.
在使用其结果之前,您需要等待每个线程完成。 pthread_join
是这里要使用的函数。
getc
(fgetc
) returns 输入 int
,这允许检查 EOF
。缩小到 char
会移除正确测试 EOF
.
thread_data_array
应该匹配 threads
数组的大小。
这是一个重构的程序:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct thread_data {
char *thread_id;
int count;
};
void *filecount(void *thread_arg){
struct thread_data *arg = thread_arg;
FILE *fp = fopen(arg->thread_id, "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open %s\n", arg->thread_id);
pthread_exit(NULL);
}
for (int c = getc(fp); c != EOF; c = getc(fp))
if (c == '\n')
arg->count++;
fclose(fp);
return NULL;
}
int main(int argc, char *argv[]){
if (argc == 1)
return 0;
argv++;
argc--;
pthread_t threads[argc];
struct thread_data thread_data_array[argc];
int total_count = 0;
for (int i = 0; i < argc; i++) {
thread_data_array[i].thread_id = argv[i];
thread_data_array[i].count = 0;
pthread_create(&threads[i], NULL, filecount,(void *) &thread_data_array[i]);
}
for (int i = 0; i < argc; i++) {
pthread_join(threads[i], NULL);
total_count += thread_data_array[i].count;
}
printf("Total line count: %d\n", total_count);
}