当前位置: 技术问答>linux和unix
关于pthread_create()第四个参数的问题
来源: 互联网 发布时间:2017-01-10
本文导语: linux下用C开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread。 这是百度百科上的定义:http://baike.baidu.com/view/1797052.htm #include int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr,...
linux下用C开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread。
这是百度百科上的定义:http://baike.baidu.com/view/1797052.htm
#include
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) 传递,如:
unix中的说:
如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。
上面的函数foo(int *a,int *b); 可以传递2个参数啊!!
问一下,第四个参数void *restrict arg 有啥用? 是运行函数的参数啥意思?
这是百度百科上的定义:http://baike.baidu.com/view/1797052.htm
#include
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) 传递,如:
#include
#include
void* foo(int *a,int *b)
{
printf("pthread :%dn",++*a);
printf("pthread :%dn",++*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 有啥用? 是运行函数的参数啥意思?
|
参考一下六楼的答案吧。
还有,第三个参数,一般没楼主这么用的吧,一般就是传线程开始执行的那个函数而已。建议楼主多看一下一些别人的代码,然后借鉴一下看别人是怎么用的
还有,第三个参数,一般没楼主这么用的吧,一般就是传线程开始执行的那个函数而已。建议楼主多看一下一些别人的代码,然后借鉴一下看别人是怎么用的
|
第三个参数传入的是线程执行函数的地址
第四个可以根据你的具体需要,传入你需要的参数。
6楼的代码有点问题,函数栈里面的地址不能当成参数传给线程创建函数,不然线程执行的时候访问函数栈的空间估计会出错。
第四个可以根据你的具体需要,传入你需要的参数。
6楼的代码有点问题,函数栈里面的地址不能当成参数传给线程创建函数,不然线程执行的时候访问函数栈的空间估计会出错。
|
调用
pthread_create(&tid,NULL,foo(&a,&b),NULL);
的时候
其实是先做
void* Fun = foo(&a,&b);
然后再
pthread_create(&tid,NULL,Fun,NULL);
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,段失败错误
关于楼主的程序的主要执行流程为:
err=pthread_create(&tid,NULL,foo(&a,&b),NULL);
1,先执行一次foo(&a,&b)并获得返回值,在这里很显然返回值是个随机数(大抵就是eax了)
2,这个返回值作为新线程的入口地址(线程入口地址是个随机数哦),参数是NULL,执行新线程
3,段失败错误
|
err=pthread_create(&tid,NULL,foo(&a,&b),NULL);
运行函数 是指的foo这个函数
运行函数的参数 是指的foo的参数,也就是a和b
这里的第四个参数NULL用的好像不太对,应该想办法把&a和&b从这里传进去
运行函数 是指的foo这个函数
运行函数的参数 是指的foo的参数,也就是a和b
这里的第四个参数NULL用的好像不太对,应该想办法把&a和&b从这里传进去
|
我来看看,学点知识。
|
象LZ那样应该也可以,把参数从第三个参数传进去,就用不着第四个了
|
foo(&a,&b)
括号里的&a, &b不起作用的, 这儿只需要一个函数的入口地址, 参数传不进去的
编译过不能说明问题.
括号里的&a, &b不起作用的, 这儿只需要一个函数的入口地址, 参数传不进去的
编译过不能说明问题.
|
单核的吧, 双核试试...
|
但是参数传递后这个栈并没有消失啊,我觉得没问题,请指教
|
蒽,我也这位差不多理解的,这里的&a,&b是不能传参的,只是作函数的声明,真正要传的参数在后面,如果是一个参数,就把那个变量的地址做最后一个参数,函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。
这样说应该好理解吧!
|
arg也可以这样用:
#include
#include
void* foo(void *args)
{
int *a, *b;
a = ((void**)args)[0];
b = ((void**)args)[1];
printf("pthread :%dn",++*a);
printf("pthread :%dn",++*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=%dn", a, b);
return 0;
}
|
当传递参数时,可以直接通过void *(*start_rtn)(void) 传递 长见识了
|
你创建的线程的routine是野指针函数。
|
道理很简单,下面这句话其实是先调用了foo这个函数,然后把该函数的返回值传递进去了
之所以编译不报错,那是因为void*在C里面可以隐式转换成其它类型的指针
err=pthread_create(&tid,NULL,foo(&a,&b),NULL);
之所以编译不报错,那是因为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);
比如:int i;
pthread_t pid;
pid = pthread_create(&pid, NULL, ThreadProc, (void*)&i);