linux c-pthreads:局部变量的问题

时间:2011-05-23 14:34:23

标签: c linux pthreads

尝试用线程计算斐波纳契数。它总是返回1.有任何建议吗?

我的代码:

#include <stdio.h>  
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
/* compile with -lpthread */
void*  fibo (void* param) {
    int    a,b,n;
    pthread_t thread_a, thread_b;
    int ret;

    n = (int) param;
    if (n>1)
    {    pthread_create(&thread_a,NULL,fibo,(void*)(n-1));    
        pthread_create(&thread_b,NULL,fibo,(void*)(n-2));
        pthread_join(thread_a,(void**)&a);
        pthread_join(thread_b,(void**)&b);
        ret=a+b;
    }
    else    ret=1;
    return (ret);    
    /*pthread_exit((void**)ret);*/
}

int main(int argc,char* argv[]) {
    pthread_t thread_id;
    int n,ret;
    n=atoi(argv[1]);
    pthread_create(&thread_id,NULL,fibo,(void*)n);
    pthread_join(thread_id,(void**)&ret);
    printf("s(%d)=%d\n",n,ret);
    return 0;
}

3 个答案:

答案 0 :(得分:6)

我猜你可能在64位系统上。

您的问题出在pthread_join:

int n,ret;
pthread_join(thread_id,(void**)&ret);

在64位系统上,int是32位,但void*是64位。所以你试图在一个32位宽的变量中存储64位。结果,你覆盖堆栈上的其他位置,通常只会造成大量的事情。确保将值检索为真void *,事情应该更好。更好的是,使用void*指针作为真正的指针;例如,您可以将指向int的指针作为线程函数参数传递,并将其用作参数,然后将结果写入同一位置。

顺便说一下,即使没有任何警告开关,GCC也会对此发出警告:

test.c:30: warning: cast to pointer from integer of different size

请不要忽略这些警告。

答案 1 :(得分:1)

有一个错误:

n = (int) param;

param void * 。所以,你将指针转换为 int ,这可能是一个负数,并且控件传递给 else 分支:)

编辑,但仍有一点需要注意:error: cast from 'void*' to 'int' loses precision

答案 2 :(得分:0)

线程不使用相同的局部变量,因为局部变量在堆栈上,并且每个线程都有自己的堆栈。线程执行共享全局变量,除非它们是显式线程本地的。

您可以使用pthread_key_create和相关函数在pthreads中创建线程局部存储。

(正如葡萄藤所指出的那样,这不是重点,因为你的错误与线程无关)