使用C中的线程的Fibonacci序列

时间:2015-12-14 15:44:05

标签: c multithreading pthreads fibonacci

我用C编写了一个程序来生成一个带有n个数字的Fibonacci序列,其中每个Fibonacci数由一个单独的线程创建,父线程输出整个产生的Fibonacci序列但是我得到了错误的序列n> 2它有些重写值如果n> 2,则斐波那契序列数组中的最后一个元素为0。如何修复它?请找到下面的代码。

/*============================================================================
   Description :The Fibonacci sequence
  ============================================================================ */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

int n;                          // size of fibonacci sequence.
int *fibseq;                    // arry holds the value of each fibonacci term.
int i;                          // counter for the threads.

void *runn(void *arg);

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("format is:./a.out <intgervalue>\n");
        return -1;
    }                           // valdiate num of args.

    if (atoi(argv[1]) < 0)
    {
        printf("%d must be>=0\n", atoi(argv[1]));
        return -1;
    }                           // valdiate value of arg1.

    n = atoi(argv[1]);
    fibseq = (int *)malloc(n * sizeof(int));
    pthread_t *threads = (pthread_t *) malloc(n * sizeof(pthread_t));
    pthread_attr_t attr;        // set of thread attribute

    pthread_attr_init(&attr);

    for (i = 0; i < n; i++)
    {
        pthread_create(&threads[i], &attr, runn, NULL);
    }                           // End of creating threads.

    int j;

    for (j = 0; j < n; j++)
    {
        pthread_join(threads[j], NULL);
    }                           // End of wating the threads to exit.

    // printing fibseq.
    printf("The Fibonacci sequence.:");
    int k;

    for (k = 0; k < n; k++)
    {
        printf("%d,", fibseq[k]);
    }                           // End of printing fibseq.
    return 0;
}                               // End of main.

void *runn(void *arg)
{
    if (i == 0)
    {
        fibseq[i] = 0;
        pthread_exit(0);
    }                           // first fib term

    if (i == 1)
    {
        fibseq[i] = 1;
        pthread_exit(0);
    }                           // seconed fib term
    else
    {
        fibseq[0] = 0;
        fibseq[1] = 1;

        int p, pp, fibp, fibpp;

        p = (i - 1);
        pp = (i - 2);
        fibp = fibseq[p];
        // printf("fibseq[%d]%d\n",p,fibp);
        fibpp = fibseq[pp];
        // printf("fibseq[%d]%d\n",pp,fibpp);
        fibseq[i] = fibseq[i - 1] + fibseq[i - 2];
        // printf("fibseq[%d]%d,\n",i,fibseq[i]);
        pthread_exit(0);        // thread exit.
    }                           // End of else
}                               // End of run.

2 个答案:

答案 0 :(得分:1)

我看到这篇文章是从2015年12月开始的,但问题的答案很简单。原因是因为您使用两个单独的for循环来创建和加入您的线程。这是做什么导致i&lt; n线程同时创建和运行* runn函数。这意味着线程不会等待更新数组。

它们应该在一个for循环中,这样thread_join语句在每个循环周期中调节每个线程。正如我在下面所做的那样。

for (i = 0; i < n; i++)
{
    pthread_create(&threads[i], &attr, runn, NULL);
    pthread_join(threads[i], NULL);
}   

现在你的线程一次只能通过你的* runn函数。从而解决您的问题。

在旁注中,您似乎在* runn函数的底部有一些不必要的代码,这不是必需的,只是重做您已经完成的工作。

 fibseq[0] = 0; //this is unnecessary, because from your first threads fibseq[0] should 
                //already equal 0
 fibseq[1] = 1; //same for here this value should be equal to 1 already

此外,这是不必要的。虽然如果我理解正确,这用于调试目的吗?

int p, pp, fibp, fibpp;

p = (i - 1);
pp = (i - 2);
fibp = fibseq[p];
// printf("fibseq[%d]%d\n",p,fibp);
fibpp = fibseq[pp];
// printf("fibseq[%d]%d\n",pp,fibpp);

else语句所需的唯一相关代码在这里

fibseq[i] = fibseq[i - 1] + fibseq[i - 2];
pthread_exit(0);        // thread exit.

我希望这有助于回答这个问题。

答案 1 :(得分:0)

Fibonnaci序列不适合并行化解决方案。实际上closed-form solution实际上是condition variable并不太难以计算,几乎肯定比基于线程的解决方案更快:

Fn = (φn - ψn) / √5

其中φ = (1 + √5) / 2ψ = (1 - √5) / 2

修改 - 在我的系统上,n&gt;的已关闭表单会有所不同71由于累积的舍入错误;使用任意精度库会有所帮助。

但是,如果您决定开展此项工作,则必须牢记以下几点:

  1. 除非已计算fibseq[i]fibseq[i-1],否则无法计算fibseq[i-2];您将需要使用mutex暂停执行线程i,直到线程i-1i-2完成;

  2. 您有一个竞争条件,其中main正在更新i的值,而线程正在尝试使用i的值同一时间。您可以使用Solution with multiple formulas来同步i的访问,但老实说,更好的解决方案是将i作为参数传递给线程(传递地址不会有帮助;您将遇到相同的同步问题)。