TerminateThread不要使用的證據
2011-01-24 10:21
162 查看
听过无数次不要TerminateThread,只是工作中常用,貌似也没有什么问题。今天在高强度测试中发现了一个不可原谅的错误。参看下面的例子
DWORD __stdcall mythread(void* )
{
while( true )
{
char* p = new char[1024];
delete p;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE h = CreateThread(NULL, 0, mythread, NULL, 0, NULL);
Sleep(1000);
TerminateThread(h, 0);
h = NULL;
char* p = new char[1024]; //这里会死锁,过不去
delete p;
return 0;
}
为什么死锁呢?new操作符用的是小块堆,整个进程在分配和回收内存时,都要用同一把锁。如果一个线程在占用该锁时被杀死(即临死前该线程在new或delete操作中),其他线程就无法再使用new或delete了,表现为hang住。
《核心编程》里明确提醒不要TerminateThread,但原因并不是血淋淋滴。今天发现的这个bug印证了此书的价值。
另注:许多临时的网络操作经常用TerminateThread,作为网络不通时的退出机制,以后要改改了。比如让该线程自生自灭,自行退出。
DWORD __stdcall mythread(void* )
{
while( true )
{
char* p = new char[1024];
delete p;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE h = CreateThread(NULL, 0, mythread, NULL, 0, NULL);
Sleep(1000);
TerminateThread(h, 0);
h = NULL;
char* p = new char[1024]; //这里会死锁,过不去
delete p;
return 0;
}
为什么死锁呢?new操作符用的是小块堆,整个进程在分配和回收内存时,都要用同一把锁。如果一个线程在占用该锁时被杀死(即临死前该线程在new或delete操作中),其他线程就无法再使用new或delete了,表现为hang住。
《核心编程》里明确提醒不要TerminateThread,但原因并不是血淋淋滴。今天发现的这个bug印证了此书的价值。
另注:许多临时的网络操作经常用TerminateThread,作为网络不通时的退出机制,以后要改改了。比如让该线程自生自灭,自行退出。
相关文章推荐
- 不要轻易使用TerminateThread中止线程
- 不要轻易使用TerminateThread中止线程
- TerminateThread 不要使用的证据
- 尽量不要使用TerminateThread与SuspendThread
- 不要使用没有升级保证的PKM软件
- 在熟练使用2B铅笔前,请不要打开Axure
- 存储过程或函数中不要使用库名
- 永远不要在Java中使用String(至少也尽量少用)
- 尽量不要使用MATLAB
- 使用SSH证书(不要密码)登陆远程服务器
- 不要对不同类型使用三元运算符[C++]
- 不要使用equals方法对AtomicXXX进行是否相等的判断
- 尽量不要使用gb2312避免乱码
- 能使用html/css解决的问题就不要使用JS
- Ecshop安装的坑,建议不要使用!
- 不要在精确计算中使用float和double类型
- 学会使用临时表优化,切记不要乱用临时表(记录一)
- 不要使用sun.misc.BASE64Encoder
- 不要使用SBJSON(json-framework)
- php cookie 作用范围–不要在当前页面使用你的cookie