【问题标题】:Segmentation fault when trying to create multiple threads for file IO:尝试为文件 IO 创建多个线程时出现分段错误:
【发布时间】:2019-10-19 03:09:48
【问题描述】:

我在运行以下程序时遇到了分段错误。我
我正在尝试制作一个执行 100 次的多线程程序:

  1. 打开文件。
  2. 读取文件的最后一行(每行包含一个数字)。
  3. 数字加 3。
  4. 在文件末尾追加新编号。
  5. 关闭文件。 线程数由用户指定。 当我创建 2 个线程时,此代码运行正确, 但是当我尝试创建 1 或不同于 2 的数字时, 它显示分段错误。

我正在使用信号量在线程之间进行同步。 你知道为什么会这样吗?

主要部分:

    for(i=0;i<NumberOfThreads;i++)  {
        if (pthread_create( pid[i], NULL, subthread, NULL ) != 0) {
            fprintf(stderr, "pthread_create failed with i = %d. errno = %d, %s\n",i, errno, strerror(errno));
            break;
        }
    }

    for(i=0;i<NumberOfThreads;i++)  {
        pthread_join(*pid[i], NULL);
    }   
    return 0;
}

void *subthread(void) {
    int i ;
    int temp ;
    char ch;
    int offset =0 ;
    FILE * fd1 ;
    FILE * fd2 ;
    for(i=0 ;i<100;i++) {
        sem_wait(&sem1);
        fd1 = fopen (NameOfFile,"r");
        fseek (fd1,-2,SEEK_END);
        offset=-2;
        while((ch=getc(fd1)) !='\n')
        {   
            offset=offset-1;
            fseek (fd1,offset,SEEK_END);
        }
        fscanf(fd1,"%d",&temp); 
        fclose(fd1);
        fd2 = fopen (NameOfFile,"a");
        temp=temp+3;
        fprintf(fd2,"\n%d",temp);
              printf("%d\n",temp);
        fclose(fd2);
        sem_post(&sem1);
    }
    pthread_exit(0);
}

这只是代码的一部分。

当我运行代码并提供 1 个线程作为输入时,它会显示分段错误。对于 2 个线程,执行是正确的。 对于超过 2 个线程,它再次显示分段错误

当我尝试调试以查看导致分段错误的原因时,日志显示函数 PTHREAD_CREATE 导致它。

【问题讨论】:

  • pid 是如何定义的?
  • 我注意到了一些快速的事情:首先pthread_create 返回错误,没有指定设置errno。其次,如果pthread_create 有错误,那么加入线程的下一个循环将循环甚至未创建的线程。崩溃的可能原因是:您可能不会让pid[i] 指向任何地方有效(但如果没有正确的minimal reproducible example,就很难说)。
  • 阅读你的线程函数,还有其他问题。例如getc 正在返回一个int。如果您想与 EOF 进行比较,这一点很重要。
  • @IngoLeonhardt 它被定义为“pthread_t * pid[NumberOfThreads+1];”
  • @makululaj 你在为指针数组定义内存吗?

标签: c multithreading file-io operating-system semaphore


【解决方案1】:

对于pthread_create(),作为第一个参数传递的指针必须指向pthread_create() 写入线程ID 的有效位置。 但正如您在评论中所说,pid 被定义为

    pthread_t * pid[NumberOfThreads+1];

这是一个最初不指向有效位置的指针数组。它们可能为 NULL 或不确定,具体取决于数组的定义方式。

我建议你把定义改成

   pthread_t pid[NumberOfThreads+1];

并致电 pthread_create(pid+i,....)pthread_create(&amp;pid[i],...); 并使用 pid[i] 而不是 *pid[i] 进行其他 pthread_...() 呼叫

猜你喜欢
  • 1970-01-01
  • 2021-08-08
  • 2021-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
  • 2018-05-01
相关资源
最近更新 更多