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.cppint 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/

C++ 如何在类中创建线程相关推荐

  1. windows系统中创建线程常用哪几个函数,有什么区别?

    windows系统中创建线程常用哪几个函数? 在windows系统中创建线程的函数有: CreadThread,AfxBeginThread,_beginthread,_beginthreadex. ...

  2. java 线程中创建线程_如何在Java 8中创建线程安全的ConcurrentHashSet?

    java 线程中创建线程 在JDK 8之前,还没有办法在Java中创建大型的线程安全的ConcurrentHashSet. java.util.concurrent包甚至没有一个名为Concurren ...

  3. Java Singleton类中的线程安全性的示例代码

    Java Singleton类中的线程安全性的示例代码 Singleton是最广泛使用的创建设计模式之一,用于限制应用程序创建对象.在实际应用程序中,数据库连接或企业信息系统(EIS)等资源是有限的, ...

  4. Java Singleton类中的线程安全

    Singleton is one of the most widely used creational design pattern to restrict the object created by ...

  5. JAVA中创建线程的三种方法及比较

    JAVA中创建线程的方式有三种,各有优缺点,具体如下: 目录 一.继承Thread类来创建线程 二.实现Runnable接口来创建线程 三.通过Callable和Future来创建线程 四.三种方式创 ...

  6. Java中创建线程的三种方式

    Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)继承Thread类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行体. ...

  7. JAVA中创建线程池的五种方法及比较

    之前写过JAVA中创建线程的三种方法及比较.这次来说说线程池. JAVA中创建线程池主要有两类方法,一类是通过Executors工厂类提供的方法,该类提供了4种不同的线程池可供使用.另一类是通过Thr ...

  8. 使用Thread类来创建线程

    使用Thread类来创建线程 定义一个线程类 自定义了一个线程类 让它不停的打印内容 让线程运行 步骤一,实例化 步骤二,调start方法

  9. (1)定义圆Circle类,包含radius半径属性,求面积方法,求周长方法,返返回圆对象的详细信息的方法(2)在测试类中创建长度为5的Circle[]数组,用来装5个圆对象

    import java.util.Random;class Circle{double radius;double area;double perimeter;// 面积public void ger ...

最新文章

  1. 注册asp.net 4.0 到iis
  2. html5基础知识点常用标签
  3. 安装Nvida 显示环境
  4. 【Flink】Flink 消费 kafka报错 写入 es 死信队列 FetchSessionHandler DisconnectException
  5. webpack 合并压缩_webpack 打包压缩js和css的方法示例
  6. java for新循环_java新特性-新式for循环(For_Each)
  7. linux下vi编辑器的命令大全,linux下VI编辑器命令大全(超级完整版)
  8. Myeclipse8.6中安装SVN插件
  9. dell R710 更换raid卡后,raid卡信息没有了,处理方案
  10. Python修改图片分辨率
  11. Swift3.0学习笔记-Error Handling
  12. 查询电脑ip地址方法
  13. php 计算今天周几,php如何计算当前日期是周几
  14. 给SSD(固态硬盘)编程
  15. 解决fileReader读取文件乱码
  16. MT6737/MT6737T/MT6737M处理器功能介绍,MT6737芯片资料
  17. mysql 5.7 winx64_mysql 5.7.17 winx64安装配置方法图文教程
  18. python-day18(正式学习)
  19. blos禁止计算机休眠,HP EliteBook 和 ProBook 笔记本电脑 - 升级 BIOS 后,计算机可能无法进入待机或休眠状态...
  20. 「人物特写」清华大学邓志东:“特征提取+推理”的小数据学习才是AI崛起的关键...

热门文章

  1. 2022七夕适合送什么蓝牙耳机?好用又便宜蓝牙耳机推荐
  2. 温故valse|2014XJTU-MengDeyu Matrix Factorization with unknown noise
  3. MySQL无备份未开启二进制的日志,恢复数据库的数据
  4. java获取随机数方法_JAVA获取随机数
  5. matlab mda,MATLAB中最基本函数plot()的用法
  6. SQLAlchemy动态表名
  7. 如何在Windows上打开命令提示符
  8. 一、卫星导航定位系统基础(1)
  9. 消息队列的五种使用场景
  10. 2019年php工资,总结2019年开发者对PHP发展有哪些看法?