2005年8月的存档

宝宝哭闹可能的情况

2005年08月23日 星期二

老婆怕我不会看孩子,专门给我写的:
1. 渴了,给点水喝(如拉肚子,可加点蒙脱石)
2. 饿了,给点奶粉,温了再喝
3. 热了,闷了,可抱到凉爽的地方透透气
4. 想尿了或拉了,一般不会太闹,把不出来就顺其自然好了,可以给穿纸尿裤,别卡着肉
5. 想睡了,给点奶或水喝,就慢慢睡了
6. 想要什么东西,如果是不该给的,可以用和她玩玩别的东西代替
7. 不想躺了,或者坐了,那就让她站着玩,或者抱她转转,看看她喜欢看的灯光,还有音乐,空气

MFC 线程的一个问题

2005年08月10日 星期三

我们公司的服务器程序一直运行得很好,但在用户一台特别高配置(2G内存,8CPU)的机器上出问题了。根据Drwtsn32的输出,查出来问题出在MFC中thrdcore.cpp中第59行

44:UINT APIENTRY _AfxThreadEntry(void* pParam)
45:{
46:    _AFX_THREAD_STARTUP* pStartup = (_AFX_THREAD_STARTUP*)pParam;

58:        _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
59:        pThreadState->m_pModuleState = pStartup->pThreadState->m_pModuleState;

出错时,pStartup->pThreadState 已经是非法值了,而pStartup是作为线程处理函数的参数传入并赋值的。

再看调用_AfxThreadEntry的地方:

385: BOOL CWinThread::CreateThread(DWORD dwCreateFlags, UINT nStackSize,
386:    LPSECURITY_ATTRIBUTES lpSecurityAttrs)
387:{

398:    _AFX_THREAD_STARTUP startup; memset(&startup, 0, sizeof(startup));
399:    startup.pThreadState = AfxGetThreadState();

414:    // create the thread (it may or may not start to run)
415:    m_hThread = (HANDLE)_beginthreadex(lpSecurityAttrs, nStackSize,
416:        &_AfxThreadEntry, &startup, dwCreateFlags | CREATE_SUSPENDED, (UINT*)&m_nThreadID);

问题就可能出在startup是个局部变量,当_AfxThreadEntry尚未执行完毕时,有可能CWinThread::CreateThread()很快完成退出,导致startup内容被更改。特别是在多CPU的机器上,可能性更大?

不用MFC的线程,直接用C库函数_beginthread,解决此问题。折腾了好几天。