关于C++类中成员函数传入pthread_create的问题以及相关函数参数的理解

参考链接

[1]. Linux 线程池的概念与实现
[2]. 【C语言】如何理解【void(*)(void)】
[3]. 关于typedef void (*sighandler_t)(int)的理解
[4]. C++类中this指针的理解
[5]. C++ 调用PTHREAD_CREATE函数时,传入类中的成员报错。解决方法。
[6]. C++ pthread_create传递静态函数及其参数
[7]. 对于void* 的理解

问题引入

C++中线程传入类内成员函数时,需要将该成员函数定义为静态成员函数[1]):

//threadpool.hpp
#include <iostream>
#include <cstdio>
#include <queue>
#include <stdlib.h>
#include <pthread.h>
using namespace std;

typedef void (*handler_t)(int);
#define MAX_THREAD 5
//任务类
class ThreadTask
{
    public:
        ThreadTask()
        {

        }
        //将数据与处理方式打包在一起
        void setTask(int data, handler_t handler)
        {
            _data = data;
            _handler = handler;
        }
        //执行任务函数
        void run()
        {
            return _handler(_data);
        }
    private:
        int _data;//任务中处理的数据
        handler_t _handler;//处理任务方式
};

//线程池类
class ThreadPool
{
    public:
        ThreadPool(int thr_max = MAX_THREAD)
            :_thr_max(thr_max)
        {
            pthread_mutex_init(&_mutex, NULL);
            pthread_cond_init(&_cond, NULL);
            for (int i = 0; i < _thr_max; i++)
            {
                pthread_t tid;
                int ret = pthread_create(&tid, NULL, thr_start, this);
                if (ret != 0)
                {
                    printf("thread create error\n");
                    exit(-1);
                }
            }
        }
        ~ThreadPool()
        {
            pthread_mutex_destroy(&_mutex);
            pthread_cond_destroy(&_cond);
        }
        bool taskPush(ThreadTask &task)
        {
            pthread_mutex_lock(&_mutex);
            _queue.push(task);
            pthread_mutex_unlock(&_mutex);
            pthread_cond_signal(&_cond);
            return true;
        }
        //类的成员函数,有默认的隐藏参数this指针
        //置为static,没有this指针,
        static void *thr_start(void *arg)
        {
            ThreadPool *p = (ThreadPool*)arg;
            while (1)
            {
                pthread_mutex_lock(&p->_mutex);
                while (p->_queue.empty())
                {
                    pthread_cond_wait(&p->_cond, &p->_mutex);
                }
                ThreadTask task;
                task =p-> _queue.front();
                p->_queue.pop();
                pthread_mutex_unlock(&p->_mutex);
                task.run();//任务的处理要放在解锁之外
            }
            return NULL;
        }
    private:
        int _thr_max;//线程池中线程的最大数量
        queue<ThreadTask> _queue;//任务缓冲队列
        pthread_mutex_t _mutex; //保护队列操作的互斥量
        pthread_cond_t _cond; //实现从队列中获取结点的同步条件变量
};

上面代码中:

class T.. {
	int ret = pthread_create(&tid, NULL, thr_start, this);
 	...
 }

在类中thr_strat定义为:

       //类的成员函数,有默认的隐藏参数this指针
       //置为static,没有this指针,
static void *thr_start(void *arg)
        {
            ThreadPool *p = (ThreadPool*)arg;
            while (1)
            {
                pthread_mutex_lock(&p->_mutex);
                while (p->_queue.empty())
                {
                    pthread_cond_wait(&p->_cond, &p->_mutex);
                }
                ThreadTask task;
                task =p-> _queue.front();
                p->_queue.pop();
                pthread_mutex_unlock(&p->_mutex);
                task.run();//任务的处理要放在解锁之外
            }
            return NULL;
        }

类的成员函数,有默认的隐藏参数this指针,设为为static,没有this指针是什么意思?
为何要将成员函数设为static?
类中this的返回值是什么?
错误出现在哪?
在这里插入图片描述
运行报错,第三个参数类型不匹配:
在这里插入图片描述

pthread函数原型

头文件

#include <pthread.h>

函数声明:

int  pthread_create(pthread_t *tidp, const  pthread_attr_t *attr,
					( void *)(*start_rtn)( void *), void  *arg);

若线程创建成功,则返回0。若线程创建失败,则返回出错编号;
(对于(void*) (*) (void*) 指一个参数为void*,返回值为void*的函数指针[2][3] )
参数
第一个参数为指向线程 标识符的 指针。
第二个参数用来设置线程属性,一般为NULL。
第三个参数是线程运行函数的起始地址。
最后一个参数是运行函数的参数。

解决

C++中,我们知道在类中成员函数调用类内的成员变量或成员函数时,会隐式调用this指针[4][5],也就是说,上例中类成员函数加上this指针后,类型为void* (Box::) (void*)的成员函数指针,而pthread_create参数类型为void* (*) (void*)两个不同的类型,肯定不会匹配。

既然错误出现在类中成员被隐式加上this,那么加上static变为静态成员函数以后,就不会加上this指针。

静态成员函数不能访问类内的非静态成员,但只需要在pthread_create时将this指针传入,就可以使得静态成员函数访问类内非静态成员[5]

传入成员函数参数

上面如果需要给函数传入其他参数,可以使用数组的方式[6]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值