读书人

关于pthread_create()第四个参数的有关

发布时间: 2012-08-02 11:35:25 作者: rapoo

关于pthread_create()第四个参数的问题
linux下用C开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread。
  这是百度百科上的定义:http://baike.baidu.com/view/1797052.htm
#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void), void *restrict arg);

Returns: 0 if OK, error number on failure
 由 restrict 修饰的指针是最初唯一对指针所指向的对象进行存取的方法,仅当第二个指针基于第一个时,才能对对象进行存取。对对象的存取都限定于基于由 restrict 修饰的指针表达式中。 由 restrict 修饰的指针主要用于函数形参,或指向由 malloc() 分配的内存空间。restrict 数据类型不改变程序的语义。 编译器能通过作出 restrict 修饰的指针是存取对象的唯一方法的假设,更好地优化某些类型的例程。
  第一个参数为指向线程标识符的指针。
  第二个参数用来设置线程属性。
  第三个参数是线程运行函数的起始地址。
  最后一个参数是运行函数的参数。

当传递参数时,可以直接通过void *(*start_rtn)(void) 传递,如:

C/C++ code
#include<stdio.h>#include<pthread.h>void* foo(int *a,int *b){printf("pthread :%d\n",++*a);printf("pthread :%d\n",++*b);}int main(){int a=0;int b=0;pthread_t tid;int err;err=pthread_create(&tid,NULL,foo(&a,&b),NULL);foo(&a,&b);return 0;}

unix中的说:
如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。
上面的函数foo(int *a,int *b); 可以传递2个参数啊!!
问一下,第四个参数void *restrict arg 有啥用? 是运行函数的参数啥意思?

[解决办法]
err=pthread_create(&tid,NULL,foo(&a,&b),NULL);
运行函数 是指的foo这个函数
运行函数的参数 是指的foo的参数,也就是a和b
这里的第四个参数NULL用的好像不太对,应该想办法把&a和&b从这里传进去
[解决办法]
我来看看,学点知识。
[解决办法]
象LZ那样应该也可以,把参数从第三个参数传进去,就用不着第四个了
[解决办法]
foo(&a,&b)
括号里的&a, &b不起作用的, 这儿只需要一个函数的入口地址, 参数传不进去的

编译过不能说明问题.
[解决办法]
arg也可以这样用:
C/C++ code
#include<stdio.h>#include<pthread.h>void* foo(void *args){int *a, *b;a = ((void**)args)[0];b = ((void**)args)[1];printf("pthread :%d\n",++*a);printf("pthread :%d\n",++*b);}int main(){int a=0;int b=0;void *arg[2] = {&a, &b};pthread_t tid;int err;err=pthread_create(&tid,NULL,foo,arg);pthread_join(tid, NULL);printf("main: a=%d, b=%d\n", a, b);return 0;}
[解决办法]
单核的吧, 双核试试...
[解决办法]
参考一下六楼的答案吧。
还有,第三个参数,一般没楼主这么用的吧,一般就是传线程开始执行的那个函数而已。建议楼主多看一下一些别人的代码,然后借鉴一下看别人是怎么用的
[解决办法]
第三个参数传入的是线程执行函数的地址
第四个可以根据你的具体需要,传入你需要的参数。
6楼的代码有点问题,函数栈里面的地址不能当成参数传给线程创建函数,不然线程执行的时候访问函数栈的空间估计会出错。
[解决办法]
当传递参数时,可以直接通过void *(*start_rtn)(void) 传递 长见识了
[解决办法]
探讨

第三个参数传入的是线程执行函数的地址
第四个可以根据你的具体需要,传入你需要的参数。
6楼的代码有点问题,函数栈里面的地址不能当成参数传给线程创建函数,不然线程执行的时候访问函数栈的空间估计会出错。

[解决办法]
你创建的线程的routine是野指针函数。
[解决办法]
调用
pthread_create(&tid,NULL,foo(&a,&b),NULL);
的时候
其实是先做
void* Fun = foo(&a,&b);
然后再
pthread_create(&tid,NULL,Fun,NULL);

[解决办法]
毫无疑问6楼的程序没有问题,关于参数在栈里面,在这里面也没有问题,因为6楼调用了pthread_join函数,主线成会一直等到子线程执行完毕,在子线程执行完毕前,主线程栈不会被释放。

关于楼主的程序的主要执行流程为:
err=pthread_create(&tid,NULL,foo(&a,&b),NULL);
1,先执行一次foo(&a,&b)并获得返回值,在这里很显然返回值是个随机数(大抵就是eax了)
2,这个返回值作为新线程的入口地址(线程入口地址是个随机数哦),参数是NULL,执行新线程
3,段失败错误

[解决办法]

探讨
调用
pthread_create(&tid,NULL,foo(&a,&b),NULL);
的时候
其实是先做
void* Fun = foo(&a,&b);
然后再
pthread_create(&tid,NULL,Fun,NULL);

[解决办法]
道理很简单,下面这句话其实是先调用了foo这个函数,然后把该函数的返回值传递进去了
之所以编译不报错,那是因为void*在C里面可以隐式转换成其它类型的指针
err=pthread_create(&tid,NULL,foo(&a,&b),NULL);

[解决办法]
查资料,路过。。。
[解决办法]
pthread_create第四个参数就是程序传给线程的参数
比如:int i;
pthread_t pid;
pid = pthread_create(&pid, NULL, ThreadProc, (void*)&i);

读书人网 >UNIXLINUX

热点推荐