模拟自主运行的对象(live object)

  C++提供了封装对象的方法,但是没有提供多线程的支持,如果需要产生多个同时自主运行的对象(live-object),就需要定义我们自己的多线程类。MSDN中的《Using Multithreading and C++ to Generate Live Objects》对这个有趣的技术进行了详细的介绍。

       废话少说,先来看一下产生一个支持多线程类的结构,下面以animate_object为例,先看一下animate_object的构造函数:

animated_object::animated_object(LPSTR lpImageName, short sType)
    
    
    
    
{
    
    
  < Initialize some member variables here. >
    
    
  hThread = CreateThread(NULL,
    
    
                         0,
    
    
                        (LPTHREAD_START_ROUTINE)ObjectThreadRoutine,
    
    
                         this,
    
    
                         0,
    
    
                        (LPDWORD)&this->dwIDThread);
    
    
  iStatus = (hThread != (HANDLE)NULL);
    
    
};
    
    

可以看到,在构造函数中产生了一个线程,hThread, 用于表示该对象所联系的对象,并且用iStatus表示是否成功产生了该线程,其中hThread作为private成员,其并不为外界所知,外部环境获得该对象的信息的唯一方式就是通过iStatus,这样实现了数据的封装,而且iStatus还可以用于表示所有初始化工作的成功或者失败

       下面是线程函数。由于线程函数不能够是非静态成员函数,所以需要使用一个全局函数

long WINAPI ObjectThreadRoutine(animated_object *fpObj)
    
    
{ 
    
    
 return (fpObj->MoveAndDraw());
    
    
} 
    
    

该全局函数实际上是一个stub function, 在函数内部调用了animated_object 对象的成员函数MoveAndDraw,为了让该全局函数可以使用animated_object的私有函数,需要将该全局函数声明为animated_object的友员函数。

       下面是析构函数

         animated_object::~animated_object(void)
    
    
{
    
    
  if (iStatus)
    
    
  {
    
    
   WaitForSingleObject(hThread,INFINITE);
    
    
   CloseHandle(hThread);
    
    
  };
    
    
  DeleteObject(hImage);
    
    
  MessageBeep(-1);
    
    
}; 
    
    

当对象析构的时候,在析构函数内部等待线程结束,然后关闭线程,注意只有当初始化成功(iStatus0)的时候,才会调用这些cleanup的工作,现在唯一的问题就是:如果该线程自己调用析构函数,就会产生死锁(A调用BB返回的条件是A已经结束),这里可以采用postMessage的方式,特别要注意的是如果使用sendMessage,仍然会产生死锁(可以用共享变量的方法避免死锁)关闭的方式,在线程函数中使用postMessage将关闭自己的消息发送给外部控制线程,由外部控制线程关闭线程,这样在调用析构函数的时候就不会产生死锁的问题了。

       同步问题:当产生多个该类的实例的时候,如果需要访问共享变量,需要使用互斥同步的方法,下面是animated_object的核心部分

long animated_object::MoveAndDraw(void)
    
    
{ int iTempX, iTempY;
    
    
  HDC hDC;
    
    
  while(!bFinished)
    
    
    {
    
    
      iTempX = iX+iXVelocity;
    
    
      iTempY = iY+iYVelocity;
    
    
 
    
    
/* The next four IF statements check whether a wall has been hit after a move.
    
    
   If yes, the position is reset to the wall, the direction reversed,
    
    
   and a random value added. */
    
    
 
    
    
< Wall-collison detection code follows here... */  
    
    
 
    
    
      EnterCriticalSection(&csSerializeDraw);
    
    
      hDC=GetDC(the_pond->hWndApplication);
    
    
 
    
    
< Erase the old image from the screen: >
    
    
 
    
    
      BitBlt(hDC,iX,iY,iImageWidth,iImageHeight,NULL,0,0,WHITENESS);
    
    
      iX = iTempX;
    
    
      iY = iTempY;
    
    
      iCalories-=MOVE_DEDUCTION;
    
    
 
    
    
/* Do three things here to determine whether one has died:  */
    
    
/* (a) Do additional per-move work, depending on the object type. */
    
    
/* (b) Determine whether we have enough fuel left to survive. */
    
    
/* (c) Ask the pond whether a collision has occurred. */
    
    
 
    
    
      if (!ObjectSpecificThreadRoutine(hDC) ||    // LOOK HERE!
    
    
          iCalories < 0 ||
    
    
          !the_pond->NewCoordinates(iHandle,iX,iY))
    
    
        bFinished=TRUE;
    
    
      else
    
    
/* Redraw the object. */
    
    
 
    
    
< Redraw code is in here.>
    
    
 
    
    
      ReleaseDC(the_pond->hWndApplication,hDC);
    
    
      LeaveCriticalSection(&csSerializeDraw);
    
    
/* Delay the object before moving on. */
    
    
      Sleep(DELAY);
    
    
    };   // end of while loop. Going past here means we are dead...
    
    
/* Inform the window that the thread has terminated, so it can clean up the object. */
    
    
 
    
    
  PostMessage(the_pond->hWndApplication,WM_OBJECT_DIED,(WPARAM)iHandle,NULL);
    
    
  return(TRUE);
    
    
};
    
    

       结论:通过使用C++的封装特性和多线程,可以很好的模拟live object,其他复杂的应用也可以通过这种方式进行扩展,可以模拟bolzman机这种需要同步运行的程序,并且作为并行程序在多CPU环境下“真正”的并行。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 、可私信6博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 、可私信6博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值