创建线程时的常见错误

创建线程时的常见错误,第1张

创建线程时的常见错误

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"< 

问题在于
写法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()>’
       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()>’
         _M_invoke(_Index_tuple<_Indices...>)

正确的初始化线程的方式是

Thread A;
std::thread *NewTask = new std::thread(&Thread::threadFunc,&A);
//或者如果这个函数是在Class体内,可以直接用this指针表示

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5593876.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存