日期:2014-05-16  浏览次数:20674 次

关于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);