【问题标题】:C Program exits without any outputC程序退出没有任何输出
【发布时间】:2017-04-17 00:19:44
【问题描述】:

这有一个关于多线程问题Here 的先前问题。现在的问题是程序在没有任何输入的情况下退出。该程序从作为参数给出的文本文件中获取输入,并执行。它应该只包含用空格分隔的数字,如果有任何其他字符,它应该给出一个错误,就像在 row_check 函数中所做的那样。谁能建议它为什么会退出而没有任何错误?。

#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<ncurses.h>
const unsigned int NUM_OF_THREADS = 9;
typedef struct thread_data_s {
char *ptr;
int row_num;
} thread_data_t;

void report(const char *s,int w,int q);

void* row_check(void* data)
{
    thread_data_t *my_data_ptr = data;
    int j, flag;

    flag=0x0000;

    for(j = 0; j < 9; j++)
{
    flag |= 1u << ( (my_data_ptr->ptr)[j] - 1 );

    if (flag != 0x01FF){
        report("row", my_data_ptr->row_num, j-1);
    }
}   

return NULL;
}

void report(const char *s,int w,int q)
{
   printf("\nThe sudoku is INCORRECT");
   printf("\nin %s. Row:%d,Column:%d",s,w+1,q+1);
   getchar();

   exit(0);
 }


 int main(int argc, char* argv[])
 {
     int i,j;
     char arr1[9][9];
     FILE *file = fopen(argv[1], "r");
     if (file == 0)
 {
    fprintf(stderr, "failed");
    exit(1);
 }
    int col=0,row=0;
    int num;

    while(fscanf(file, "%c ", &num) ==1) {
        arr1[row][col] = num;
        col++;

    if(col ==9)
    {
        row++;
        col = 0;
    }
 }

 fclose(file);

int n;

thread_data_t data[NUM_OF_THREADS];
pthread_t tid;
pthread_attr_t attr;


for(n=0; n < NUM_OF_THREADS; n++)
{
     data[n].ptr = &arr1[n][0];
     data[n].row_num = n;
     pthread_create(&tid, &attr, row_check, &data[n]);
}


for(n=0; n < NUM_OF_THREADS; n++)
{
     pthread_join(tid, NULL);
}


return 0;

}

【问题讨论】:

  • 更新:文件读取工作,线程也被创建。问题似乎是何时调用行检查?
  • 建议fscanf(file, " %c", &amp;num) ==1(移动空间)
  • 你试过调试吗?取决于您在哪个调试器上使用哪个操作系统和编译器
  • 为了便于阅读和理解:1) 一致地缩进代码。在每个左大括号 '{' 后缩进。在每个右大括号 '}' 之前不缩进。建议每个缩进级别使用 4 个空格。 2) 遵循公理:每行只有一个语句,并且(最多)每条语句有一个变量声明。
  • 将程序的各种元素命名为相同的名称是一种糟糕的编程习惯,只有大小写不同。 IE。 FILEfile

标签: c multithreading pthreads


【解决方案1】:

以下代码中的问题之一,它将解释为什么应用程序会这么快就存在...

以下代码不会加入它创建的所有线程(因此应用程序会在线程完成运行之前退出并终止线程):

thread_data_t data[NUM_OF_THREADS];
pthread_t tid;
pthread_attr_t attr;

for(n=0; n < NUM_OF_THREADS; n++)
{
     data[n].ptr = &arr1[n][0];
     data[n].row_num = n;
     pthread_create(&tid, &attr, row_check, &data[n]);
}


for(n=0; n < NUM_OF_THREADS; n++)
{
     pthread_join(tid, NULL);
}

如您所见,代码仅保存指向其中一个线程的指针(tid 中的值始终被替换,覆盖现有数据)并加入该线程(而不是全部)。

这可能会更好地构造为:

thread_data_t data[NUM_OF_THREADS];
pthread_t tid[NUM_OF_THREADS];

for(n=0; n < NUM_OF_THREADS; n++)
{
     data[n].ptr = &arr1[n][0];
     data[n].row_num = n;
     pthread_create(tid + n, NULL, row_check, &data[n]);
}


for(n=0; n < NUM_OF_THREADS; n++)
{
     pthread_join(tid[n], NULL);
}

这样,应用程序将在返回之前等待所有线程完成其任务(并报告任何错误)。

【讨论】:

    【解决方案2】:

    谁能建议为什么它会退出而没有任何错误?

    是的,

    当9行拼图结果全部正确时,贴出的代码没有动作,它只是优雅地退出。

    并进一步混淆逻辑。

    贴出的代码只检查最后创建的线程,当该线程退出时,程序退出,这并不意味着其他线程已经退出

    另一个严肃的细节。对pthread_create() 的调用传递了attr 变量的地址,但该变量包含声明该变量的堆栈上的垃圾。由于代码没有为线程设置任何特定属性,强烈建议消除变量并在pthread_create()的第二个参数中简单地使用NULL

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      • 2021-11-07
      • 2023-03-30
      • 2023-03-09
      • 2020-11-05
      相关资源
      最近更新 更多