【问题标题】:Seg Fault when reading from file, and using pthread_create从文件读取和使用 pthread_create 时出现段错误
【发布时间】:2016-02-22 00:42:02
【问题描述】:

每当我运行我的代码时,我都会经历 4 次迭代,读取文件并创建一个 pthread,直到它出现 ID 11 的段错误。

段错误是由我的打印 ln 引起的: printf("%s %s\n", "用包调用lab_manifes_alignment", *package); 但是为什么这会导致段错误呢?

停下来?

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>

pthread_mutex_t mutex;

FILE *packageList;

void *submitPackage(void * packageReq){
    char ** package = packageReq;
    strcat(packageReq, " | sh lab_manifest_alignment.sh");
    printf("%s %s\n", "Calling lab_manifes_alignment with package", *package);
    system(packageReq);
    return NULL;
}


int main(){
    int numThreads;
    pthread_t threads[numThreads];

    //Init mutex
    if(pthread_mutex_init(&mutex, NULL)){
            fprintf(stderr, "Error initializing mutex");
    }

    int rc;
    FILE *packageList = fopen("package_list.txt", "r");
    if(packageList == NULL){
            fprintf(stderr, "ERROR: cannot open file.\n");
            return 1;
    }

    int i = 0;
    char line[128];

    while ( fgets ( line, sizeof line, packageList ) != NULL ){ 
    /* read a line spawn as many threads as needeed*/
        printf("%s %d, %s\n", "line: ",i, line);
        rc = pthread_create(&(threads[i]), NULL, submitPackage, line);

        if(rc){
            printf("ERROR: return code from pthread_create() is %d\n", rc);
            exit(EXIT_FAILURE);
        }
        i++;
    }

    numThreads = i;

    for(i = 0; i < numThreads; i++){
            pthread_join(threads[i], NULL);
    }

    fclose(packageList);
    return 0;

}

【问题讨论】:

  • 你是不是故意造成并发问题?
  • 这有点粗鲁?抱歉我好多年没用过pthread了......如果有这么多明显的问题是什么问题?
  • 不,这并不粗鲁。并发是问题之一。正如我之前问过的,这是故意的吗?
  • 我没有引入任何故意的问题,我是 C 的业余爱好者

标签: c segmentation-fault pthreads file-read


【解决方案1】:

我认为这里有问题:

char ** package = packageReq;

尝试改变:

char ** package = &packageReq;

【讨论】:

    【解决方案2】:

    pthread_t threads[numThreads];numThreads这里没有初始化,你应该选择线程的最大值或者动态分配。

    fgets ( line, sizeof line, packageList ) 将 128 个字节读入line(数组的大小),但strcat(packageReq, " | sh lab_manifest_alignment.sh"); 在其后面添加了一些内容。这是您的段错误的原因。您应该增加数组的大小并减少fgets 中的大小参数。

    您的主线程中的下一次迭代将覆盖您的 line 数组,而线程正在使用它。您应该使用二维数组或在每次迭代中分配一个缓冲区,并在使用它后在线程中释放它。每个线程都必须获得自己的缓冲区,而不是每个线程都一样。

    char ** package = packageReq; 应该是char *package = packageReq; 并删除printf 处的*

    【讨论】:

    • 请注意,我的 numThreads 确实设置为 i,这等于我的文件中的行数。从使用 strcat 更改为此处的第一个选项后:stackoverflow.com/questions/1383649/… 我得到了 seg 错误退出。谢谢,我忘了认为我需要这些行的缓冲区..
    • 我注意到了,但是在声明数组的过程中,它的值是未初始化的,因此它会调用未定义的行为。
    • 啊..谢谢..也..为什么是 2D 缓冲区?难道我不能只制作一个 1D 共享缓冲区,使用互斥体,然后让每一行都从中推送和弹出吗?
    • 当然可以,但是由于只有1个线程(包括主线程)可以同时使用缓冲区,这就像是一个单线程程序。
    • 所以我已经让缓冲区工作了......但是当我改变 char ** package = packageReq;到 char *package = packageReq;我现在收到错误:无法将 (char *) 设置为类型 (void **) --- using char ** package = &packageReq;是正确的,但仍会发出警告...有关如何消除此警告的任何信息?
    猜你喜欢
    • 1970-01-01
    • 2020-08-14
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多