浏览 2357 次
锁定老帖子 主题:void* 泛型指针一点小技巧
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-01-10
void *有人把它叫为generic pointer,中文翻译为泛型指针。一般来说,它的用法应该是作为指针来用,比如下面的例子
int main() { int i; char c; void *the_data; i = 6; c = 'a'; the_data = &i; printf("the_data points to the integer value %d\n", *(int*) the_data); the_data = &c; printf("the_data now points to the character %c\n", *(char*) the_data); return 0; }
这里the_data就是作为一个可以任意指向的多功能指针来用的,但是下面的例子里面
#include <pthread.h> #include <stdio.h> #define NUM_THREADS 5 void *PrintHello(void *threadid) { long tid; tid = (long)threadid; printf("Hello World! It's me, thread #%ld!\n", tid); pthread_exit(NULL); } int main (int argc, char *argv[]) { pthread_t threads[NUM_THREADS]; int rc; long t; for(t=0; t<NUM_THREADS; t++){ printf("In main: creating thread %ld\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } /* Last thing that main() should do */ pthread_exit(NULL); }
在上面的pthread传递参数的时候,t或者threadid明明就不是指针,这里为什么也用void*。pthread_create函数里面的定义就规定必须传递void*的参数,这是我们是不能选的,如果按照一定要是指针的思维,程序应该是下面的才对
#include <iostream> #include <pthread.h> //#include <stdio.h> #include <stdlib.h> #define NUM_THREADS 5 using namespace std; void *PrintHello(void *threadid) { long tid; cout<<"Checking generic pointer"<<threadid<<endl; tid = *(long*)threadid; cout<<"Hello world! It's me, thread #"<< tid <<endl; pthread_exit(NULL); } int main() { pthread_t threads[NUM_THREADS]; int rc; long t; for(t=0; t<NUM_THREADS; t++){ cout<<"In main: creating thread"<<t<<endl; rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&t); if(rc){ cout<<"ERROR; return code from pthread_create() is"<<rc<<endl; exit(-1); } } pthread_exit(NULL); //cout << "Hello World!" << endl; return 0; }
可以这样的话,你会发现在PrintHello里面打印的threadid是错误的,是什么原因呢?
解答: 如果用上面的方式,传递的就是t的地址给threadid,那么PrintHello的时候,主程序里面的t的修改是另外一个线程,所以不能保证PrintHello打印的这个地址的数没有被主程序修改过。
那么怎么传递才对?我们上面的倒数第二个其实是对的,这个时候t的值其实是作为地址传递给threadid,然后用long转换的时候就又变成了原来的值了,虽然他们其实不是地址,但是被编译器或者程序当作地址来做个转换又何妨!
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-01-10
pthread_create的传参确实有些麻烦,如果有多于一个参数,就必须封装成结构体,且最好用全局或堆变量,否则考虑到生命周期,很可能会出错。
|
|
返回顶楼 | |