找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3583|回复: 1

共享内存文件的问题,是不是有什么限制?

[复制链接]
发表于 2008-4-29 09:53:20 | 显示全部楼层 |阅读模式
在WIN32平台,我现在在作一个项目,用到了共享内存文件(ACE_Pagefile_Memory_Pool).想法是这样的:首先建立一个资源文件列表,参数为墨认.之后每有客户端在资源列表中添加一条信息,就建一个共享内存文件用于保存客户端程序发送来的数据,如果客户端程序长时间没有在对应的共享内存文件内写入数据,那就删除这个共享内存文件,并且把资源文件列表中的信息也一同删除.现在遇到几个问题:
1.共享内存文件的建立.测试要建至少20个共享内存文件用于保存客户端程序发来的数据,可是建立的时候出错,"unknown error",我想是不是ACE在共享内存文件建立上有限制啊,可是我找不到这方面的资料,有用过的前辈能否告诉我一些相关的信息.
2.多个定时器.我用多线程实现了多个REACTOR模式的定时器,可是一运行就出错,也定位不到代码,不过可能是我的代码写的不对,前辈能否指点一下.这个文件我问过了,可winston回答过于简单了,请说的再详细一些,我把相关的代码贴上来.
  1. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. static int worker(void *arg)
  3. { //工作线程函数
  4.   ACE_UNUSED_ARG(arg);
  5. ACE_DEBUG((LM_DEBUG,
  6.   "Thread (%t) Created to do some work\n"));
  7. CLogFileRes *ThreadParam = (CLogFileRes*)arg ;
  8. // ACE_Process_Mutex ProMutex(ACE_TEXT("me"));
  9. // ProMutex.acquire();
  10. ACE_DEBUG ((LM_INFO,
  11.   ACE_TEXT ("(%t) worker hold \n")));
  12. ACE_DEBUG((LM_DEBUG,
  13.   "id = %d\tbaseaddr = %ld file = %s start = %d\n",
  14.   ThreadParam->m_ui32id,
  15.   ThreadParam->m_ui32BaseAddr,
  16.   ThreadParam->m_pLogFile,
  17.   ThreadParam->m_bThreadStart));
  18. //建立指定位置的共享区域
  19. ALLOCATOR *pMemoryFile_allocator;
  20. ACE_Pagefile_Memory_Pool_Options  options((void *)(ThreadParam->m_ui32BaseAddr));
  21.     TCHAR *name_ = ThreadParam->m_pLogFile;
  22. ACE_NEW_RETURN (pMemoryFile_allocator,
  23.   ALLOCATOR (name_,  name_,  &options),  -1);
  24. //建立定时器定时扫描共享区
  25. ACE_Time_Value interval(3);   
  26. CFileSaveTimer_Handler  
  27.   *pFileSave_Handler = new CFileSaveTimer_Handler(pMemoryFile_allocator,
  28.                                                   ThreadParam );
  29. ACE_Reactor::instance ()->schedule_timer(pFileSave_Handler,  0, interval, interval);
  30. ACE_Reactor::instance ()->run_reactor_event_loop ();//--->>>>>>程序在这在出错了,弹窗
  31. pMemoryFile_allocator->sync();
  32. delete pMemoryFile_allocator;
  33. pMemoryFile_allocator = 0;
  34. delete ThreadParam;
  35. ThreadParam = 0;
  36. ACE_DEBUG ((LM_INFO,
  37.   ACE_TEXT ("(%t) worker exit\n")));
  38. return 0;
  39. }
  40. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  41. //共享资源区定时扫描器类
  42. class CFileResTimer_Handler : public ACE_Event_Handler
  43. {
  44. public:
  45. CFileResTimer_Handler(HASH_MAP *hashmap)  :m_map(hashmap)
  46. {
  47.   m_ui32max = 0;
  48. };
  49. int handle_timeout (const ACE_Time_Value &current_time,  const void * = 0)
  50. {
  51.   time_t epoch = ((timespec_t)current_time).tv_sec;
  52.   m_ui32max = static_cast<ACE_UINT32> (m_map->current_size ());
  53.   ACE_DEBUG ((LM_INFO,
  54.    ACE_TEXT ("handle_timeout: %s    \n"), ACE_OS::ctime(&epoch));
  55.   //查找未建立线程标识的数据
  56.   //找到的话建立工作线程,把CLogFileRes当参数传给线程函数
  57.   ACE_Process_Mutex ProMutex(ACE_TEXT("me"));
  58.   ProMutex.acquire();
  59.   ACE_DEBUG ((LM_INFO,
  60.    ACE_TEXT ("(%t) main hold ,main hold\n")));
  61.   int i = 0;
  62.   for (HASH_MAP::iterator iter = m_map->begin (); iter != m_map->end (); iter++)
  63.   {
  64.    int key = (*iter) .ext_id_;
  65.    CLogFileRes newRes ;
  66.    int result = m_map->find (key, newRes, g_pFileRes);
  67.    if (result == -1)
  68.    {
  69.     ACE_DEBUG ((LM_ERROR,
  70.     ACE_TEXT ("Could not find record for %d\n"),
  71.     key));
  72.    }
  73.    else
  74.    {
  75.     if (!newRes.m_bThreadStart)
  76.     {
  77.      //找到的话建立工作线程,把CLogFileRes当参数传给线程函数
  78.      CLogFileRes newestRes = newRes;
  79.      newestRes.m_bThreadStart = true;
  80.      int newresult = m_map->rebind(key,newestRes,key,newRes,g_pFileRes);
  81.      if (newresult == -1)
  82.      {
  83.       ProMutex.release();
  84.       ACE_DEBUG ((LM_INFO,
  85.        ACE_TEXT ("(%t) main no hold ,main no hold\n")));
  86.       return 0;
  87.      }
  88.      //
  89.      //传入线程的参数在线程退出之前不能空,否则线程内的参数就会为空会弹窗
  90.      //解决办法:NEW一个参数传入线程,在退出线程时DELETE参数
  91.      CLogFileRes *pThreadParam = new CLogFileRes(newRes);
  92.      if(ACE_Thread::spawn((ACE_THR_FUNC)worker, (void*)pThreadParam) == -1)
  93.      {
  94.       ACE_DEBUG((LM_DEBUG,
  95.        "Error in spawning thread  Record name: %d|addr:%d|file:%s|start = %d\n",
  96.        newRes.m_ui32id,
  97.        newRes.m_ui32BaseAddr,
  98.        newRes.m_pLogFile,
  99.        newRes.m_bThreadStart));
  100.      }
  101.     }
  102.    }
  103.   }
  104.   ProMutex.release();
  105.   return 0;
  106. }
  107. private:
  108. ACE_UINT32     m_ui32max;             //共享资源区的当前有用资源数
  109. HASH_MAP       *m_map;
  110. };
  111. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  112. int ACE_TMAIN (int argc, ACE_TCHAR *[])
  113. {
  114. //建立日志文件资源内存共享文件
  115. ACE_Pagefile_Memory_Pool_Options options;
  116.     ACE_NEW_RETURN (g_pFileRes,
  117.   ALLOCATORROOT (MAP_NAME, MAP_NAME, &options),
  118.   -1);
  119. //建立共享内存哈希表
  120.     g_map = smap (g_pFileRes);
  121. if (g_map == 0)
  122. {
  123.   return 0;
  124. }
  125. addRecords(g_map, g_pFileRes);
  126. ACE_Time_Value interval(1);    //扫描共享资源区的时间间隔1秒
  127. CFileResTimer_Handler  
  128.   *pFileResScan_Handler = new CFileResTimer_Handler(g_map);
  129. ACE_Reactor::instance ()->schedule_timer(pFileResScan_Handler,
  130.                                        0,
  131.             interval,
  132.             interval);
  133. ACE_Reactor::instance ()->run_reactor_event_loop ();
  134. g_pFileRes->sync ();
  135. ACE_OS::system(ACE_TEXT("pause"));
  136. g_map->close(g_pFileRes);
  137. g_map = 0;
  138. delete g_pFileRes;
  139. g_pFileRes = 0;
  140. delete pFileResScan_Handler;
  141. pFileResScan_Handler = 0;
  142.   return 0;
  143. }
复制代码
这个代码是我通过ACE程序员指南里面的例子改的.各位前辈给点意见.
 楼主| 发表于 2008-4-29 09:53:34 | 显示全部楼层
代码编译不过去,缺少文件。
因为运行时的上下文的关系,需要调试才了解,毕竟程序是你写的。
说说我的想法:
1、加强调试的能力,推荐《Windows程序调试》一书,象此类bug,其实都是容易找到原因的类型,因为每次运行都出错。最难的是偶发类型的。
2、调试最基本的技巧只有几个,乐意与你分享:
   设置合适的断点,出错时候,看上下文堆栈,就能看到错误的来源
   看内存,就能看到对象的状态是否正确
如果无法进入ACE的模块内,说明你没有放置对应的调试信息符号文件在路径内,如*.pdb。
3、Reactor可以反复调用schedule_timer的,你可以跟踪一下代码,它对定时器支持的很好。

希望对你有所帮助。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-23 13:34 , Processed in 0.027449 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表