加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

[转载]回调函数与多线程

(2012-05-15 21:23:02)
标签:

转载

原文地址:回调函数与多线程作者:ColorWolf

遇到一个数据采集卡的上层处理程序,数据的获取是通过采集卡自身带有的一个函数,此函数采取回调的方式来执行用户自定义的操作,如下所示

AI_EventCallBack (cardID, 1, DBEvent, (U32) AI_DBCallBack_Record))

第三个参数是用户对数据进行操作的入口函数,当采集卡将数据采集好时就会让系统调用AI_DBCallBack_Record,我在AI_DBCallBack_Record 中首先将数据转成电压值并对其进行分组以进行后面的显示操作,最后PostMessage给显示处理的类。程序运行起来后发现整个采集过程很流畅,采集的同时进行界面操作也不会卡,但是这其中没有运用多线程技术,很是奇怪。难道回调函数的执行时另外开辟了一个线程?

于是上网查资料

 

回调函数是在调用方的线程空间里面

调用方是在主线程空间里面运行就是在主线程空间,否则不是...

如果是主线程空间里面的,   而且他要发生的时候我的主线程很忙,怎么办?

像EnumChildWindows这种你一调它控制权就交给它了,主线程已经在执行它了,没有很忙的说法。

 

///////////////////////////////////

本来回调与线程之间没多大关系,只是线程是采用回调的方式来执行你的代码,这个是它们之间存在的一点联系。

回调函数:
一般用于模块解耦,提供功能扩展用。
要清楚的认识回调函数,需要分清这两者,调用方(即接口声明方)、(即被调用方)实现方。
事实上回调函数无处不再,控制台中的main、WIN32中的WinMain、WINDRV中的DriverEntry都是回调函数,所以你会发现回调函数的原型都是固定的(当然main的标准原型可以有好几种,不在此讨论),但其函数体均由你自己来实现,然后在适当的时机被调调用方用(对于刚才所说的那几种情况则是由crt、crt、system进程在程序初始化时进行调用,对于驱动程序框架则完全是回调机制)。

线程:
概念不用说了,这里只说过程。你需要实现一个函数体(函数原型是实现规定好的),然后调用线程开启函数向系统传递一个函数指针开启一个线程。然后由系统通过刚才传递进来的函数指针再来调用,所以就实现了你的线程过程。

实现机理:
(回调)调用方提供一个注册接口给(回调)实现方,并通常会提供一个回调上下文让你绑定一个任意型数据进去(通常是平台字节数大小,32位则是4字节,当然这个是通常,实际提供与否看人家心情了)。
比如:
typedef (void *DATACALLFUN)(BYTE *lpBuf, DWORD dwSize, DWORD dwUser);
BOOL RegisterDataCallBackFun(DATACALLFUN fun, DWORD dwUser);
调用方内部将此函数指针和用户数据保存起来,然后在适当的时候进行调用
if (NULL != m_funptr)
{
  m_funptr(m_lpDataBuffer, m_dwSize, m_dwUser);
}

/////////////////////////////////////////////

综上所述,回调函数不是另一个线程,如果在采集程序里采取这种方法,应该不是个很好的办法。当采集任务繁重时会出现AI_DBCallBack_Record函数还没有执行完而采集卡的数据已经准备好的情况

 

0

后一篇:zhuan 多线程
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有