1.linux下 pthread_create创建多线程编译报错
error: invalid conversion from ‘void (*)()’ to ‘void* (*)(void*)’ [-fpermissive]
pthread_create(&id,NULL,Test,NULL);
比如你自定义了一个线程函数
void Test()
{
}
随后将这个函数作为传参调用pthread_create进行线程创建
pthread_t id ;
pthread_create(&id,NULL,Test,NULL);
就会出现上述报错,为什么会出现这种报错呢?首先看pthread_create的函数签名
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
参数1:pthread_t类,是一个线程标识符
参数2:线程属性,一般被设置为NULL
参数3:线程函数
怎么理解void *(start_routine) (void )
定义了一个函数指针 start_routine,他的返回值是void 输入参数是void
参数4:线程函数对应的实际输入参数
2.利用C++11得std::thread创建线程
int Test1(int a ,int b)
{
while(true)
{
std::cout<<"Test1"<<std::endl;
sleep(1);
}
return 1;
}
int main(int argc, char *argv[])
{
//CreatRegisterTask2();
int a =1;
int b =2;
std::thread NewTask(Test1,a,b); //如果是使用类实例方法,第二个参数要带上类指针
if( NewTask.joinable())
{
NewTask.join();
}
return 1;
}
问题在于
写法1: std::thread NewTask(Test1,a,b);
这一行代码不管是如上得定义,还是改为
写法2: std::thread NewTask(&Test1,a,b);
都可以编译通过,而且都可以正常运行,就…有点奇怪,额。。难道是构造函数重载了?…
真是搞不懂…
3.类的实例方法可以创建线程么?
思考一个问题,类的实例方法与类的静态方法不一样,类的静态方法在编译起就已经确定了(在类的域名空间作用下),而类的实例方法需要在实例化类的时候才会确定。C++编译器在编译时会将类的实例对象地址作为第一个传参传给该方法,比如一个叫threadFunc的类实例方法,在编译后,他的函数签名会变成 threadFunc(Thread * this,void * agr);
Class Thread
{
//...省略其他
threadFunc(void * arg){}
}
所以在创建新的线程时,如果这样写就会报错
std::thread *NewTask = new std::thread(&Thread::threadFunc);
/usr/include/c++/4.8/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<int (Thread::*)()>()>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/4.8/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<int (Thread::*)()>()>’
_M_invoke(_Index_tuple<_Indices...>)
正确的初始化线程的方式是
Thread A;
std::thread *NewTask = new std::thread(&Thread::threadFunc,&A);
//或者如果这个函数是在Class体内,可以直接用this指针表示