C++ 如何在类中创建线程

C++ 如何在类中创建线程

问题描述:

一般我们在启线程时,都是把线程函数写成全局函数来使用,但是如果要把线程操作写成类,线程函数放在类里面在C++编译会不通过。

在C++类中创建线程会有报错:
下面以一个简单的类进行举例
EXTERNAL.h文件

#ifndef _RADIO_EXTERNAL_H_
#define _RADIO_EXTERNAL_H_

class CRadioTask : public CTaskBase
{
public:
	CRadioTask();
	virtual ~CRadioTask();
	virtual int Run();
	int WriteNetMessage(BYTE *pBuffer, USHORT uLen);
private:
	BYTE m_line_id;
	BYTE m_ConnectStatus;   ////0-断开,1-连接
	BYTE m_sendFlag; //0-未发送,1-已发送
};
#endif

在EXTERNAL.cpp文件的成员函数中直接创建线程会导致编译不通过

int CRadioTask::Run()
{
   OsBeginTask( &m_ThreadId, WriteNetMessage,NULL);
   return 0;
}
int CRadioTask::WriteNetMessage(BYTE *pBuffer, USHORT uLen)
{
	int iReVal = 0;
	if(m_ConnectStatus)
	{
		iReVal =OsWriteSocket(m_SocketId, pBuffer, uLen, &uLen);
		if(iReVal)
		{
sysprint(0, 0, "[%s] OsWriteSocket error rc=%d", m_TaskName, iReVal);
			CloseSocket();
		}
	}	
	return iReVal;
}

在这里插入图片描述编译不通过

原因分析:

在创建线程的api 中传入的线程函数需要在编译时确定地址,如果是普通的类函数,编译时不能确定地址,需要创建类的对象才能获取。把线程的执行函数写成static 函数,或者是全局函数,函数地址在编译时是确定的


解决方案一:

当WriteNetMessage为成员函数时,CRadioTask 继承CTaskBase类的创建线程函数,在CTaskBase类中将线程的执行函数TaskFunc定义为静态函数。
在类中定义线程函数,但是需要将线程函数定义为静态的。

class CTaskBase
{
public:
    CTaskBase() : m_ThreadId(0)
	{};
    virtual ~CTaskBase() {};
    //线程启动
    int start()
    {
OsBeginTask( &m_ThreadId, TaskFunc, (void *)this );
		return 0;
    }
protected:
    THREAD_ID m_ThreadId;
    //将线程的执行函数定义为静态类
    static int TaskFunc(void *lpParam)
    {
        CTaskBase *pThis = (CTaskBase *)lpParam;
        return pThis->Run();
    }
    virtual int Run() = 0;
};

//CRadioTask 继承 CTaskBase
class CRadioTask : public CTaskBase
{
public:
	CRadioTask();
	virtual ~CRadioTask();
	virtual int Run();
private:
	BYTE m_line_id;
	BYTE m_ConnectStatus;   ////0-断开,1-连接
	BYTE m_sendFlag; //0-未发送,1-已发送
};

// main.cpp

int main()
{
    CRadioTask* PTask=new CRadioTask();
    PTask->start(); //创建线程成功
    sleep(20);
    return 0;
}

解决方案二:

当WriteNetMessage为全局函数时,
将要传入线程的函数,写成全局函数,不作为类的成员;然后把类的实例(pTask)作为参数传入线程中要调用的函数(WriteNetMessage),这样就可以调用类中的成员函数和变量(m_TaskName,m_ConnectStatus)了。

int WriteNetMessage(CRadioTask* pTask,BYTE *pBuffer, USHORT uLen)
{
	int iReVal = 0;
	if(pTask->m_ConnectStatus)
	{
		iReVal = OsWriteSocket(m_SocketId, pBuffer, uLen, &uLen);
		if(iReVal)
		{
sysprint(0, 0, "[%s] OsWriteSocket error rc=%d", pTask->m_TaskName, iReVal);
			CloseSocket();
		}
	}	
	return iReVal;
}

int CRadioTask::Run()
{
   OsBeginTask( &m_ThreadId, WriteNetMessage,NULL);
   return 0;
}

参考:https://tnie.github.io/2016/11/03/multiThread/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值