尝试用线程计算斐波纳契数。它总是返回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;
}
答案 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中创建线程局部存储。
(正如葡萄藤所指出的那样,这不是重点,因为你的错误与线程无关)