如何修复 pthread_create 调用中的分段错误

The*_*ere 1 c pthreads

我当前的代码有问题。我正在开发一个项目,在该项目中,我使用线程从终端读取一组文件,并了解单个文件组和总文件组中有多少行。我的问题是,当我运行代码时,我得到一个核心转储,当我通过 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);
}
Run Code Online (Sandbox Code Playgroud)

Oka*_*Oka 5

总结一些评论:

char thread_id;
thread_id = *thread->thread_id;
Run Code Online (Sandbox Code Playgroud)

将为您提供文件名的第一个字符。因此,虽然是 的第一个参数的&thread_id正确类型 ( ) ,但它不是指向空终止字符串的指针。这是未定义的行为char *fopen

thread_data_array[t].count = count;
Run Code Online (Sandbox Code Playgroud)

count未初始化,其值不确定。这是未定义的行为

您需要等待每个线程完成才能使用其结果。pthread_join是这里使用的函数。

getc( fgetc) 返回类型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);
}
Run Code Online (Sandbox Code Playgroud)