【问题标题】:Multithreaded program POSIX多线程程序POSIX
【发布时间】:2015-10-23 01:17:57
【问题描述】:

这段代码用于使用多线程的斐波那契数列,但它显示了错误。你能检查一下并告诉我我必须做些什么来解决这个问题

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

int arr[100];/* array*/

typedef struct {
        int input;
        int output[100];
} thread_args;

void *thread_func ( void *ptr )/*child thread */
    {
      int i = ((thread_args *) ptr)->input;
      int x;
      ((thread_args *) ptr)->output[0]=0;
      ((thread_args *) ptr)->output[1]=1;

      for(x=2;x<i;x++)
      {
         /* ((thread_args *) ptr)->output[x]= 
        ((thread_args *)   ptr)->output[x-1] 
         +((thread_args *) ptr)->output[x-2]; */
      }
      return NULL;
     }


   int main(int argc, char *argv[])
    {
      pthread_t thread;
      thread_args args;
      int status;
      int x;
      int result;
      int thread_result;
      if (argc < 2) return 1;
      int n = atoi(argv[1]);
      args.input = n;
      status = pthread_create(&thread,NULL,thread_func,(void*) &args );
      // main can continue executing
      // Wait for the thread to terminate.
      pthread_join(thread, NULL);
      for(x=0;x<n;x++)
      {
       arr[x]=args.output[x];/* get the result*/
       printf("Fibonacci is %d.\n", arr[x]);/*print all numbers*/
      }
    }

    return 0;
   }

【问题讨论】:

  • 欢迎来到 SO。请更详细地描述您遇到的错误和位置。您也可以使用编辑按钮来删除一式三份的措辞并缩进您的代码,使其变得可读。谢谢。
  • 开始,在编译时,始终启用所有警告,然后修复这些警告。 (对于 gcc,至少使用:-Wall -Wextra -pedantic -std-c99
  • 发布的代码甚至还没有开始编译。第一个问题是 main() 中的 'for()' 循环之后的额外右大括号 '}'
  • 为了可读性,请一致地缩进代码。建议在每个缩进级别使用 4 个空格。 4 个空格允许在不占用可用页面宽度的情况下进行多个级别的缩进,并且即使使用可变宽度字体也足够宽。建议在每个左大括号后缩进:'{' 并且在每个右大括号之前不缩进:'}' 建议在代码块周围留一个空行(for、while、do...while、if、else 等)
  • 你没有提到你得到了什么错误。请按照@JensGustedt 的建议添加错误的详细信息。如果您的错误是计算出的斐波那契数列值的错误值,请注意用于“输出”和“arr”的数据类型为“int”,它将正常工作到斐波那契数列中的第 46 个元素。对于更高的元素,您需要使用 64 位数据类型(unsigned long long int 或 uint64_t),然后在打印值时调用 printf() 中的 '%llu' 说明符。

标签: c arrays multithreading pthreads posix


【解决方案1】:

以下代码:

  • 编译干净
  • 执行所需的功能
  • 生成正确的输出
  • 正确检查错误
  • 消除代码混乱

代码不检查最大命令行值 100,您可以添加该检查

#include <stdio.h> // printf(), perror()
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <pthread.h> // pthread_create(), pthread_exit(), pthread_join()

int arr[100];/* array*/

typedef struct
{
        int input;
        int output[100];
} thread_args;


void *thread_func ( void *ptr )/*child thread */
{
    thread_args *arg = (thread_args *)ptr;
    size_t i = (size_t)arg->input;
    arg->output[0] = 0;
    arg->output[1] = 1;

    for( size_t x=2; x<i; x++ )
    {
        arg->output[x] = arg->output[x-2] + arg->output[x-1];
    }
    pthread_exit( NULL );
} // end function: thread_func


int main(int argc, char *argv[])
{
    pthread_t thread;

    thread_args args;

    int status;
    int x;
    //int result;
    //int thread_result;

    if (argc < 2)
    {
        printf( "Usage: %s <maxFibonacci>\n", argv[0]);
        exit( EXIT_FAILURE );
    }

    // implied else, argc is correct


    int n = atoi(argv[1]);
    if( n <= 0)
    {// then command line argument not numeric or < 0
        printf( "command line arguent: %s is not a valid positive int\n", argv[1]);
        exit( EXIT_FAILURE );
    }

    // implied else, command line argument valid

    args.input = n;

    status = pthread_create(&thread,NULL,thread_func,(void*) &args );
    if( status )
    { // then error occurred
        perror( "phread_create failed to create thread" );
        exit( EXIT_FAILURE );
    }

    // implied else, pthread_create was successful

    // main can continue executing
    // Wait for the thread to terminate.
    pthread_join(thread, NULL);

    for(x=0;x<n;x++)
    {
        arr[x]=args.output[x];/* get the result*/
        printf("Fibonacci is %d.\n", arr[x]);/*print all numbers*/
    }

    return 0;
}

【讨论】:

  • 注意,由于有符号整数的最大正值的限制,在 32 位系统(4 字节整数值)上,当命令行时代码将无法打印正确的值value 大于 46 数组中的值是正确的,所以 printf() 输出可以修改为unsigned 然后打印正确的值。 IE。 printf("Fibonacci sequence %d is %u.\n", x, (unsigned)arr[x]);
  • 如先前评论中所述,32 位“int”将溢出。所以需要使用long long int作为arr[]类型等
【解决方案2】:

代码未编译

您必须删除语句之前的右括号:

返回 0;

假设你的程序在 program.c 中

你这样编译:

  1. gcc -g -Wall -Wextra -pedantic -c p.c -o program.o -I。

  2. gcc -g program.o -o program -lpthread

选项 -g 用于调试您的代码

为了进行调试,我建议使用一些图形工具,如 ddd 或 xxgdb(如果你愿意,可以使用其他工具)

当您不提供参数时,您的程序会因为以下语句而以代码 1 终止:

如果 (argc

所以现在当我像这样执行你的程序时:

./a.out 5 (例如找到 n=5 的斐波那契)

它给出这个输出:

斐波那契是 0。

斐波那契是 1。

斐波那契是 32684。

斐波那契是 0。

斐波那契是 0。

如你所见,现在结果并不好

函数 void *thread_func (void *ptr) 似乎无法正常工作

【讨论】:

  • 实际上,编译代码应该启用所有警告:建议:gcc -g -Wall -Wextra -pedantic -c program.c -o program.o -I. 然后与gcc -g program.o -o program -lpthread 链接
  • 感谢您提供的编译选项。我会更新我的帖子。像这样编译时会出现警告。以前用Posix线程的时候不习惯这样编译
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
相关资源
最近更新 更多