共享内存文件的问题,是不是有什么限制?
在WIN32平台,我现在在作一个项目,用到了共享内存文件(ACE_Pagefile_Memory_Pool).想法是这样的:首先建立一个资源文件列表,参数为墨认.之后每有客户端在资源列表中添加一条信息,就建一个共享内存文件用于保存客户端程序发送来的数据,如果客户端程序长时间没有在对应的共享内存文件内写入数据,那就删除这个共享内存文件,并且把资源文件列表中的信息也一同删除.现在遇到几个问题:1.共享内存文件的建立.测试要建至少20个共享内存文件用于保存客户端程序发来的数据,可是建立的时候出错,"unknown error",我想是不是ACE在共享内存文件建立上有限制啊,可是我找不到这方面的资料,有用过的前辈能否告诉我一些相关的信息.
2.多个定时器.我用多线程实现了多个REACTOR模式的定时器,可是一运行就出错,也定位不到代码,不过可能是我的代码写的不对,前辈能否指点一下.这个文件我问过了,可winston回答过于简单了,请说的再详细一些,我把相关的代码贴上来.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int worker(void *arg)
{ //工作线程函数
ACE_UNUSED_ARG(arg);
ACE_DEBUG((LM_DEBUG,
"Thread (%t) Created to do some work\n"));
CLogFileRes *ThreadParam = (CLogFileRes*)arg ;
// ACE_Process_Mutex ProMutex(ACE_TEXT("me"));
// ProMutex.acquire();
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%t) worker hold \n")));
ACE_DEBUG((LM_DEBUG,
"id = %d\tbaseaddr = %ld file = %s start = %d\n",
ThreadParam->m_ui32id,
ThreadParam->m_ui32BaseAddr,
ThreadParam->m_pLogFile,
ThreadParam->m_bThreadStart));
//建立指定位置的共享区域
ALLOCATOR *pMemoryFile_allocator;
ACE_Pagefile_Memory_Pool_Optionsoptions((void *)(ThreadParam->m_ui32BaseAddr));
TCHAR *name_ = ThreadParam->m_pLogFile;
ACE_NEW_RETURN (pMemoryFile_allocator,
ALLOCATOR (name_,name_,&options),-1);
//建立定时器定时扫描共享区
ACE_Time_Value interval(3);
CFileSaveTimer_Handler
*pFileSave_Handler = new CFileSaveTimer_Handler(pMemoryFile_allocator,
ThreadParam );
ACE_Reactor::instance ()->schedule_timer(pFileSave_Handler,0, interval, interval);
ACE_Reactor::instance ()->run_reactor_event_loop ();//--->>>>>>程序在这在出错了,弹窗
pMemoryFile_allocator->sync();
delete pMemoryFile_allocator;
pMemoryFile_allocator = 0;
delete ThreadParam;
ThreadParam = 0;
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%t) worker exit\n")));
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//共享资源区定时扫描器类
class CFileResTimer_Handler : public ACE_Event_Handler
{
public:
CFileResTimer_Handler(HASH_MAP *hashmap):m_map(hashmap)
{
m_ui32max = 0;
};
int handle_timeout (const ACE_Time_Value ¤t_time,const void * = 0)
{
time_t epoch = ((timespec_t)current_time).tv_sec;
m_ui32max = static_cast<ACE_UINT32> (m_map->current_size ());
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("handle_timeout: %s \n"), ACE_OS::ctime(&epoch));
//查找未建立线程标识的数据
//找到的话建立工作线程,把CLogFileRes当参数传给线程函数
ACE_Process_Mutex ProMutex(ACE_TEXT("me"));
ProMutex.acquire();
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%t) main hold ,main hold\n")));
int i = 0;
for (HASH_MAP::iterator iter = m_map->begin (); iter != m_map->end (); iter++)
{
int key = (*iter) .ext_id_;
CLogFileRes newRes ;
int result = m_map->find (key, newRes, g_pFileRes);
if (result == -1)
{
ACE_DEBUG ((LM_ERROR,
ACE_TEXT ("Could not find record for %d\n"),
key));
}
else
{
if (!newRes.m_bThreadStart)
{
//找到的话建立工作线程,把CLogFileRes当参数传给线程函数
CLogFileRes newestRes = newRes;
newestRes.m_bThreadStart = true;
int newresult = m_map->rebind(key,newestRes,key,newRes,g_pFileRes);
if (newresult == -1)
{
ProMutex.release();
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%t) main no hold ,main no hold\n")));
return 0;
}
//
//传入线程的参数在线程退出之前不能空,否则线程内的参数就会为空会弹窗
//解决办法:NEW一个参数传入线程,在退出线程时DELETE参数
CLogFileRes *pThreadParam = new CLogFileRes(newRes);
if(ACE_Thread::spawn((ACE_THR_FUNC)worker, (void*)pThreadParam) == -1)
{
ACE_DEBUG((LM_DEBUG,
"Error in spawning threadRecord name: %d|addr:%d|file:%s|start = %d\n",
newRes.m_ui32id,
newRes.m_ui32BaseAddr,
newRes.m_pLogFile,
newRes.m_bThreadStart));
}
}
}
}
ProMutex.release();
return 0;
}
private:
ACE_UINT32 m_ui32max; //共享资源区的当前有用资源数
HASH_MAP *m_map;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////
int ACE_TMAIN (int argc, ACE_TCHAR *[])
{
//建立日志文件资源内存共享文件
ACE_Pagefile_Memory_Pool_Options options;
ACE_NEW_RETURN (g_pFileRes,
ALLOCATORROOT (MAP_NAME, MAP_NAME, &options),
-1);
//建立共享内存哈希表
g_map = smap (g_pFileRes);
if (g_map == 0)
{
return 0;
}
addRecords(g_map, g_pFileRes);
ACE_Time_Value interval(1); //扫描共享资源区的时间间隔1秒
CFileResTimer_Handler
*pFileResScan_Handler = new CFileResTimer_Handler(g_map);
ACE_Reactor::instance ()->schedule_timer(pFileResScan_Handler,
0,
interval,
interval);
ACE_Reactor::instance ()->run_reactor_event_loop ();
g_pFileRes->sync ();
ACE_OS::system(ACE_TEXT("pause"));
g_map->close(g_pFileRes);
g_map = 0;
delete g_pFileRes;
g_pFileRes = 0;
delete pFileResScan_Handler;
pFileResScan_Handler = 0;
return 0;
}
这个代码是我通过ACE程序员指南里面的例子改的.各位前辈给点意见. 代码编译不过去,缺少文件。
因为运行时的上下文的关系,需要调试才了解,毕竟程序是你写的。
说说我的想法:
1、加强调试的能力,推荐《Windows程序调试》一书,象此类bug,其实都是容易找到原因的类型,因为每次运行都出错。最难的是偶发类型的。
2、调试最基本的技巧只有几个,乐意与你分享:
设置合适的断点,出错时候,看上下文堆栈,就能看到错误的来源
看内存,就能看到对象的状态是否正确
如果无法进入ACE的模块内,说明你没有放置对应的调试信息符号文件在路径内,如*.pdb。
3、Reactor可以反复调用schedule_timer的,你可以跟踪一下代码,它对定时器支持的很好。
希望对你有所帮助。
页:
[1]