博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++线程入口函数的几种方式
阅读量:5971 次
发布时间:2019-06-19

本文共 2349 字,大约阅读时间需要 7 分钟。

  hot3.png

假设线程入口函数和创建线程函数原型如下:

线程入口函数原型:
typedef void* (*FNTHREAD)(void *pParam);
其中:pParam传递给线程的参数。 并假定所有的函数、方法都编译成stdcall调用约定。
创建线程函数原型:
THREAD ThreadCreate(void *pParam, FNTHREAD fnThreadProc) ;
其中:pParam传递给线程的参数。fnThreadProc线程入口函数。THREAD函数返回类型,线程句柄。
不考虑等待线程结束、释放线程句柄...等问题。
一、全局函数作为线程的入口函数

void* FunThreadGlobal(void *pParam) ;class CThreadGlobal{public:	THREAD ThreadRun()	{		return ThreadCreate(this, FunThreadGlobal) ;	}		void* ThreadProc()	{		cout<<"CThreadGlobal"<
(pParam) ; return (p != NULL) ? p->ThreadProc() : NULL ;}

二、静态成员函数作为线程的入口函数

 

class CThreadStatic{public:	THREAD ThreadRun()	{		return ThreadCreate(this, FunThreadStatic) ;	}		void* ThreadProc()	{		cout<<"CThreadStatic"<
(pParam) ; return (p != NULL) ? p->ThreadProc() : NULL ;}

三、友元函数作为线程的入口函数

class CThreadFriend{public:	friend void* FunThreadFriend(void *pParam) ;		THREAD ThreadRun()	{		return ThreadCreate(this, FunThreadFriend) ;	}		void* ThreadProc()	{		cout<<"CThreadFriend"<
(pParam) ; return (p != NULL) ? p->ThreadProc() : NULL ;}

四、无参成员函数作为线程的入口函数

类成员函数有个隐含的this指针,对于类成员函数ReturnType Class::MemFun(ParameterList...) ;
可以看成是ReturnType MemFun(Class * this, ParameterList...) ;
因此无参的成员函数刚好可以当线程的入口函数。但C++不支持将成员函数指针强制转换成其它类型的指针,
成员函数ReturnType Class::MemFun();直接强制类型转换 FNTHREAD fun = (FNTHREAD)&Class::MemFun; 这样写法将引起编译错误。
这种方式不行,那么就换别的。条条大道通罗马,能达到目的就行。下面介绍两种实现方式:
4.1、函数模板方式

template
THREAD ThreadCreateTemplate(T *t, F f){ typedef void* (T::*THISCALLFUN)(); //指向类T的无参成员函数的指针类型 THISCALLFUN fnTcf = (THISCALLFUN)f; //这样fnTcf就保存了成员函数的地址 FNTHREAD fnFun = *(FNTHREAD*)&fnTcf ; //将fnTcf取地址以后,再取该地址的内容(成员函数的地址) return ThreadCreate(t, fnFun) ; //t就当this指针,}class CThreadTemplate{public: THREAD ThreadRun() { return ThreadCreateTemplate(this, &CThreadTemplate::ThreadProc) ; } void* ThreadProc() { cout<<"CThreadTemplate"<

4.2、变参函数方式

虽然不能将成员函数指针强制转换成其它类型的指针,但尝试发现可以把成员函数指针传给可变参数的函数。

THREAD ThreadCreateVarParam(void *pParam, ...){	FNTHREAD fnFun = NULL;	va_list pArgList ;	va_start (pArgList, pParam) ;	fnFun = *(FNTHREAD *)pArgList ;	va_end (pArgList) ;	return fnFun != NULL ? ThreadCreate(pParam, fnFun) : (THREAD)0 ;}class CThreadVarParam{public:	THREAD ThreadRun()	{		return ThreadCreateVarParam(this, &CThreadVarParam::ThreadProc) ;	}		void* ThreadProc()	{		cout<<"CThreadVarParam"<

转载于:https://my.oschina.net/osbin/blog/215125

你可能感兴趣的文章
Docker 容器监控系统初探
查看>>
【跃迁之路】【496天】刻意练习系列255(2018.06.16)
查看>>
CentOS 7服务器下Nginx安装配置
查看>>
前端笔记——JS基础(原型&&原型链)
查看>>
初探正则表达式
查看>>
如果ChannelHandler之间处理数据格式不一样,可以怎么做转换?
查看>>
css预编译--sass基础篇
查看>>
组件(7) —— 通信
查看>>
从RNN到LSTM,性能良好的神经网络到底是如何工作的?
查看>>
[效率] HHKB键盘 + Autohotkey 配置秘籍
查看>>
使用GDB等验证Golang的“编译器会为某些场合进行专门优化,避免字符串转换时的额外分配和复制操作”...
查看>>
PHP 5.6,7.0,7.1,7.2 和 HHVM 运行效率比较
查看>>
记微信网页开发单页面返回不刷新的实现
查看>>
flask笔记:部署flask
查看>>
前端结构体系
查看>>
聊聊hikari连接池的validationTimeout
查看>>
使用commons-pool管理FTP连接
查看>>
Linux服务器密钥连接——之密钥一毛一样,但是死活不成功问题
查看>>
常用前端知识积累
查看>>
MaxCompute复杂数据分布的查询优化实践
查看>>