修改ACE的Reactor模式示例中的参数后测试,依据测试结果,猜测Reactor似乎可以突破62个事件的限制。但是...

前端之家收集整理的这篇文章主要介绍了修改ACE的Reactor模式示例中的参数后测试,依据测试结果,猜测Reactor似乎可以突破62个事件的限制。但是...前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

修改ACE的Reactor模式示例中的参数后测试,依据测试结果,猜测Reactor似乎可以突破62个事件的限制。但当事件蜂拥而上时,Reactor会由于应对不及,而出现事件漏掉的现象。

下面是在 ACE 6.0.0 提供的示例 Reactors_Test 的部分源代码 (在 \ACE-6.0.0\ACE_wrappers\tests\ 目录下)。

Reactors_Test.cpp 文件部分内容

#if defined (ACE_HAS_THREADS)

ACE_Thread_Manager *thr_mgr;

static const int MAX_TASKS = 20;
...

int
Test_Task::svc (void) 
{
  ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%t) svc\n")));

  for (size_t i = 0; i < ACE_MAX_ITERATIONS; i++)
    {
      ACE_OS::thr_yield ();

      // Only wait up to 10 milliseconds to notify the Reactor.
      ACE_Time_Value timeout (0,10 * 1000); 

      if (this->reactor ()->notify (this,ACE_Event_Handler::READ_MASK,&timeout) == -1)
        {
          if (errno == ETIME)
            ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%t) %p\n"),ACE_TEXT ("notify() timed out")));
          else
            ACE_ERROR_RETURN ((LM_ERROR,ACE_TEXT ("notify")),-1);
        }
  }

  return 0;
}

int
Test_Task::handle_close (ACE_HANDLE,ACE_Reactor_Mask)
{
  return 0;
}

int
Test_Task::handle_input (ACE_HANDLE) 
{
  this->handled_++;

  if (this->handled_ == ACE_MAX_ITERATIONS)
    {
      done_count--;
      ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%t) handle_input,handled_ = %d,done_count = %d\n"),this->handled_,done_count.value ()));
    }

  ACE_OS::thr_yield ();
  return -1;
}

static void *
worker (void *args)
{
  ACE_Reactor *reactor = reinterpret_cast<ACE_Reactor *> (args);

  // Make this thread the owner of the Reactor's event loop.
  reactor->owner (ACE_Thread::self ());

  // Use a timeout to inform the Reactor when to shutdown.
  ACE_Time_Value timeout (4);

  for (;;)
    switch (reactor->handle_events(timeout))  
      {
      case -1:
        ACE_ERROR_RETURN ((LM_ERROR,ACE_TEXT ("reactor")),0);
        /* NOTREACHED */
      case 0:
        ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%t) Reactor shutdown\n")));
        return 0;
      }

  ACE_NOTREACHED (return 0);
}

#endif /* ACE_HAS_THREADS */

int
run_main (int,ACE_TCHAR *[])
{
  ACE_START_TEST (ACE_TEXT ("Reactors_Test"));

#if defined (ACE_HAS_THREADS)
  ACE_ASSERT (ACE_LOG_MSG->op_status () != -1);

  thr_mgr = ACE_Thread_Manager::instance ();

  ACE_Reactor reactor;
  ACE_ASSERT (ACE_LOG_MSG->op_status () != -1);

  Test_Task tt1[MAX_TASKS];
  Test_Task tt2[MAX_TASKS];

  // Activate all of the Tasks.

  for (int i = 0; i < MAX_TASKS; i++)
    {
      tt1[i].open (ACE_Reactor::instance ());  
      tt2[i].open (&reactor); 
    }

  // Spawn two threads each running a different reactor.

  if (ACE_Thread_Manager::instance ()->spawn
      (ACE_THR_FUNC (worker),(void *) ACE_Reactor::instance (),THR_BOUND | THR_DETACHED) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,ACE_TEXT ("%p\n"),ACE_TEXT ("spawn")),-1);

  else if (ACE_Thread_Manager::instance ()->spawn
      (ACE_THR_FUNC (worker),(void *) &reactor,-1);

  if (ACE_Thread_Manager::instance ()->wait () == -1)
    ACE_ERROR_RETURN ((LM_ERROR,ACE_TEXT ("wait")),-1);

  ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%t) all threads are finished\n")));

#else
  ACE_ERROR ((LM_INFO,ACE_TEXT ("threads not supported on this platform\n")));
#endif /* ACE_HAS_THREADS */

  ACE_END_TEST;

  return 0;
}



test_config.h文件(在 \ACE-6.0.0\ACE_wrappers\tests\ 目录下)部分内容

#ifndef ACE_TEST_CONFIG_H
#define ACE_TEST_CONFIG_H

...

size_t const ACE_NS_MAX_ENTRIES = 1000;
size_t const ACE_DEFAULT_USECS = 1000;
size_t const ACE_MAX_TIMERS = 4;
size_t const ACE_MAX_DELAY = 10;
size_t const ACE_MAX_INTERVAL = 0;
size_t const ACE_MAX_ITERATIONS = 10;
size_t const ACE_MAX_PROCESSES = 10;
size_t const ACE_MAX_THREADS = 4;

...

#endif /* ACE_TEST_CONFIG_H */


搭配修改下面三个参数测试:

1. MAX_TASKS

2. timeout(在Test_Task::svc 函数里)

3. ACE_MAX_ITERATIONS

三个参数的原值:

static const int MAX_TASKS = 20;

ACE_Time_Value timeout (0,10 * 1000);

size_t const ACE_MAX_ITERATIONS = 10;

如果把 MAX_TASKS值设成大于62(比如 100),即把每个Reactor(示例中有两个Reactor)的事件数设置超过62个,如下:

static const int MAX_TASKS = 100;

这样,如果 timeout 和 ACE_MAX_ITERATIONS 两个参数值搭配设置不当,在日志文件Reactors_Test.log(在\ACE-6.0.0\ACE_wrappers\tests\log目录下)中就会出现有事件漏掉的提示,如下:

LM_ERROR@(13432) notify: Resource temporarily unavailable

但如果搭配设置恰当,就没有这样的提示

另外,跟踪调试发现,Reactor在相应事件时调用了ACE_WFMO_Reactor::poll_remaining_handles 函数(在\ACE-6.0.0\ACE_wrappers\ace\WFMO_Reactor.cpp文件中):

DWORD
ACE_WFMO_Reactor::poll_remaining_handles (DWORD slot)
{
  return ::WaitForMultipleObjects (this->handler_rep_.max_handlep1 () - slot,this->handler_rep_.handles () + slot,FALSE,0);
}


函数字面意思是“响应余下的事件句柄”之意。

综上是否可猜测:

Reactor可以突破62个事件的限制,分批(最多62个一批)监视事件,但当事件蜂拥而上时,Reactor会由于应对不及,而出现事件漏掉的现象。

原文链接:https://www.f2er.com/react/308135.html

猜你在找的React相关文章