如何在一个mfc多线程调用函数结束时,调用另外一个函数

类成员函数作为多线程的入口函数的实现方法
我的图书馆
类成员函数作为多线程的入口函数的实现方法
通常在界面编程中,我们一方面要提供一个良好的界面环境给用户,同时后台还要做相关的应用处理,比如对数据库的查询、更新;复杂的计算处理。而这往往是很耗时的,如果界面更新和后台处理在同一个主线程中,那么界面的更新将受到后台处理程序的影响,特别是当后台程序比较耗时时,界面往往得不到及时更新,会给用户造成程序死掉的假象。对于这种情况,我们通常会采用多线程编程的方式来实现,即响应用户的操作在一个线程,而用户后台处理在另外一个线程。在有些时候,我们要新开一个线程,在这个线程里面要访问到类的成员函数和成员变量,但是CreateThread函数要求提供的线程函数必须是静态成员函数或者全局函数,这样在线程里面是不能够访问到类的成员变量的。这就是一个比较麻烦的矛盾。完整的方案如下:#include&windows.h&#include&stdio.h&#include&process.h&class test{&&&&public:&&&&test(int x):mx(x){}&&&&static unsigned int __stdcall threadProc(void* pV) { test* p = (test*)pV;&&&&&&&&p-&func();&&&&&&&&return 0;&&&&}&&&&void func()&&&&{&&&&&&&&printf("%d\n",mx);&&&&}};int main(){&&&&test x(10);&&&&_beginthreadex(0,0,test::threadProc,(void*)&x,0,0);或者m_hThread=CreateThread(NULL,NULL,CRealPlayer::MyFunction, (LPVOID)this,NULL,NULL);&&&&Sleep(100);&&&&return 0;}一种解决方案:将对象的this指针作为参数传递给线程函数,然后在线程函数里面将其转换为相应的类对象指针,在里面调用指针进行相应的操作就OK了。相应的例子如下:1.在这里创建新的线程,将this指针传递给线程函数 MyFunctionm_hThread=CreateThread(NULL,NULL,CRealPlayer::MyFunction, (LPVOID)this,NULL,NULL);2.//线程函数,在线程里面实现将CRealPlayer的member2和member3成员相加,结果放到成员member1中。这个线程函数是 static的成员函数。DWORD WINAPI CRealPlayer::MyFunction(LPVOID lpParameter){CRealPlayer * lp=(CRealPlayer *)lpPlp-&member1=lp-&member2+lp-&member3;}多线程在很多地方都有讲述,但大都作为全局函数,且不能对类的成员进行访问,本文讲述如何将一个线程定义在一个类中以及如何通过这个线程实现对类中的成员进行访问。多线程创建线程时,线程函数如果要设置成类的成员函数,则必须是静态成员函数,在此函数种不能使用非静态成员变量,如果要使用非静态成员变量,则一种比较适合线程的方法是:建立线程的时候把this作为CreateThread的一个参数(即第4个参数,就是那个LPVOID型的),然后线程里就对应pParam,例如:&&&&&&&&static UINT ThreadProc(LPVOID pParam) &&&&&&&&&{ &&&&&&&&&&&&&&&&&Your_Class *p=(Your_Class *)pP &&&&&&&&&&&&&&&&&//然后用p间接使用成员变量。&&&&&&&&&}   &&&&&&&&线程函数是回调函数,因此它必须是静态成员函数或者是类外部声明的全局函数。 函数在类中的定义在类中,多线程函数必须定义为静态函数Class CMutilThread: Public CDialog{………private:HANDLE&&&&&&&&&&hTDWORD&&&&&&&&&&&idTUINT&&&&&&&&&&&&protected:public:static&&&&&&&DWORD&&WINAPI&&ThreadPro(LPVOID lpParam);};多线程的实现多线程函数的实现(本例中每次线程被调用的时候均对计数器加1)DWORD WINAPI CMutilThread(LPVOID){CMutilThread&&*pDlg = (CMutilThread*)lpP//定义指向本类的指针,相当于this&pDlg-&couter++;&&&&//计数器加1}多线程函数的创建void CMutiThread::OnStart(){hThread = CreateThread (NULL, 0,THreadPro,this,0,idThread);}多线程的终止void CMutiThread::OnEnd(){TerminalThread(hThread,0);}//*******************************************************************************************************************************C++类成员函数直接作为线程回调函数以前写线程时要么老老实实照着声明写,要么使用C++类的静态成员函数来作为回调函数,经常会因为线程代码而破坏封装.之前虽然知道类成员函数的展开形式,但从没想过利用过它,昨天看深入ATL时无意中学会了这一招:)类成员方法是一个比较特殊的函数,它在编译时会被转化成普通函数,比如有TMyClass类:class TMyClass{&&&&void Func();};这个TMyClass::Func最终会转化成 void Func(TMyClass *this); 也就是说在原第一个参数前插入指向对象本身的this指针。我们可以利用这个特性写一个非静态类成员方法来直接作为线程回调函数,先看_beginthread函数的定义:unsigned long _RTLENTRY _EXPFUNC _beginthread (void (_USERENTRY *__start)(void *),unsigned __stksize, void *__arg);其中的第一个参数就是作为线程执行主体的回调函数。它的原型是:void Func(void *),这个void*参数是作为自定义数据传入的。对比一下上面所说的TMyClass::Func的最终形式,它正好可以符合这里的要求。现在做个实验:#include &stdio.h&#include &process.h&class TMyClass{&&&&int m_nC&&&&int m_nId;public:&&&&TMyClass(int nId,int nCount)&&&&&&&&:m_nId(nId),m_nCount(nCount)&&&&{&&&&}&&&&void _USERENTRY ThreadProc()&&&&&&&&&&&&// 类成员方法&&&&{&&&&&&&&for(int i=0; i &m_nC i++)&&&&&&// 根据m_nCount成员打印一排数字&&&&&&&&{&&&&&&&&&&&&printf("Class%d : %d\n",m_nId,i);&&&&&&&&}&&&&}};int main(int argc, char* argv[]){&&&&union {&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// 联合类,用于转换类成员方法指针到普通函数指针(试过编译器不允许在这两种函数之间强制转换),不知道有没有更好的方法。&&&&&&&&void (_USERENTRY *ThreadProc)(void *);&&&&&&&&void (_USERENTRY TMyClass::*MemberProc)();&&&&} P&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// 尽管联合里的两种函数类型现在看起来有很大不同,但它们的最终形式是相同的。&&&&TMyClass MyClass1(1,10),MyClass2(2,5); // 产生两个TMyClass对象&&&&Proc.MemberProc = &TMyClass::ThreadP&&// 转换,Proc.ThreadProc就是对应的普通函数指针了&&&&_beginthread(Proc.ThreadProc,4096,&MyClass1);&&// 开始线程,这里的Proc.ThreadProc实际上是TMyClass::ThreadProc, 它要的this指针是我们给的&MyClass1。&&&&_beginthread(Proc.ThreadProc,4096,&MyClass2);&&&&system("pause");&&&&return 0;}运行!神奇吧?:-)其实不止线程回调函数,其实只要是形如Func(void*,...)的回调函数都可以用这种方法直接使用类成员方法。(前提是第一个void*是自定义数据,也就是说它不能有其它功能)。
发表评论:
TA的最新馆藏本帖子已过去太久远了,不再提供回复功能。Linux多线程编程时如何查看一个进程中的某个线程是否存活_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Linux多线程编程时如何查看一个进程中的某个线程是否存活
来源:Linux社区&
作者:sharelearner
pthread_kill:
别被名字吓到,pthread_kill可不是kill,而是向线程发送signal。还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用signal()去抓信号并加上处理函数。
int pthread_kill(pthread_t thread, int sig);
向指定ID的线程发送sig信号,如果线程代码内不做处理,则按照信号默认的行为影响整个进程,也就是说,如果你给一个线程发送了SIGQUIT,但线程却没有实现signal处理函数,则整个进程退出。
pthread_kill(threadid, SIGKILL)也一样,杀死整个进程。如果要获得正确的行为,就需要在线程内实现signal(SIGKILL,sig_handler)了。
所以,如果int sig的参数不是0,那一定要清楚到底要干什么,而且一定要实现线程的信号处理函数,否则,就会影响整个进程。
OK,如果int sig是0呢,这是一个保留信号,一个作用是用来判断线程是不是还活着。
我们来看一下pthread_kill的返回值:成功:0线程不存在:ESRCH信号不合法:EINVAL
所以,pthread_kill(threadid,0)就很有用啦。
int kill_rc = pthread_kill(thread_id,0);
if(kill_rc == ESRCH)printf("the specified thread did not exists or already quit/n");else if(kill_rc == EINVAL)printf("signal is invalid/n");elseprintf("the specified thread is alive/n");
上述的代码就可以判断线程是不是还活着了。&
使用pthread_kill函数检测一个线程是否还活着的程序,在linux环境下gcc编译通过,现将代码贴在下面:/******************************* pthread_kill.c *******************************/#include &stdio.h&#include &stdlib.h&#include &pthread.h&#include &errno.h&void *func1()/*1秒钟之后退出*/{sleep(1);printf("线程1(ID:0x%x)退出。/n",(unsigned int)pthread_self());pthread_exit((void *)0);}void *func2()/*5秒钟之后退出*/{sleep(5);printf("线程2(ID:0x%x)退出。/n",(unsigned int)pthread_self());pthread_exit((void *)0);}void test_pthread(pthread_t tid) /*pthread_kill的返回值:成功(0) 线程不存在(ESRCH) 信号不合法(EINVAL)*/{int pthread_kill_pthread_kill_err = pthread_kill(tid,0);if(pthread_kill_err == ESRCH)printf("ID为0x%x的线程不存在或者已经退出。/n",(unsigned int)tid);else if(pthread_kill_err == EINVAL)printf("发送信号非法。/n");elseprintf("ID为0x%x的线程目前仍然存活。/n",(unsigned int)tid);}int main(){pthread_t tid1,tid2;pthread_create(&tid1,NULL,func1,NULL);pthread_create(&tid2,NULL,func2,NULL);sleep(3);/*创建两个进程3秒钟之后,分别测试一下它们是否还活着*/test_pthread(tid1);/*测试ID为tid1的线程是否存在*/test_pthread(tid2);/*测试ID为tid2的线程是否存在*/exit(0);}编译:gcc -o pthread_kill -lpthread pthread_kill.c运行:./pthread_kill///////////////////////// 运行结果 /////////////////////////////线程1(ID:0xb7e95b90)退出。ID为0xb7e95b90的线程不存在或者已经退出。ID为0xb7694b90的线程目前仍然存活。
相关阅读:
简单的Linux环境下多线程TCP服务程序框架 &
Linux下C语言实现多线程文件复制
Linux多进程多线程互斥同步例子
Linux下多线程通过蒙特卡洛法来求取pi值
Linux下的多线程定时器实现
相关资讯 & & &
& (08/01/:11)
& (09/28/:50)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款一个线程的问题,函数中启动的线程,如果该函数之后结束,那么线程会不会也跟着结束?
int func_temp()
//do something
int func()
thread_t th = thread(func_temp);
int main()
//这里func return之后线程 th 会不会也跟着return??
当然不会。main结束了跟th也没关系。你用print和sleep就可以验证。
要跟着结束了。这样的线程又有啥用呢。哈。}

我要回帖

更多关于 线程调用函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信