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

博客介绍了在C++中实现多线程类以产生自主运行对象的方法。以animate_object为例,阐述了构造函数、线程函数、析构函数的实现,解决了析构时的死锁问题,还提到多实例访问共享变量需互斥同步,可模拟复杂程序并在多CPU环境并行。

  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环境下“真正”的并行。

基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样与统计,通过模拟系统元件的故障与修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构与设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码与案例分析,便于复现和扩展应用。; 适合人群:具备电力系统基础知识和Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行与可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理与实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估与优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值