请教关于CloseHandle的问题

一线贫民_ 2017-09-11 08:26:21
#include "iostream.h"
#include "windows.h"

DWORD WINAPI Fun1(LPVOID lpParameter);
DWORD WINAPI Fun2(LPVOID lpParameter);
int ticket=100;
CRITICAL_SECTION h_section;
void main()
{
HANDLE hd2;
HANDLE hd1;
hd1=CreateThread(NULL,0,Fun1,NULL,0,NULL);
hd2=CreateThread(NULL,0,Fun2,NULL,0,NULL);
//CloseHandle(hd1); //我发现注释掉这里好像会正常,否则出现图片的问题,并且只有一个线程在跑
//CloseHandle(hd2);
InitializeCriticalSection(&h_section);
Sleep(4000);
DeleteCriticalSection(&h_section);
}

DWORD WINAPI Fun1(LPVOID lpParameter)
{
while (TRUE)
{
EnterCriticalSection(&h_section);
if(ticket>0)
{
Sleep(1);
cout<<"thread 1:"<<ticket--<<endl;
}
else
break;
LeaveCriticalSection(&h_section);
}
return 0;
}

DWORD WINAPI Fun2(LPVOID lpParameter)
{
while (TRUE)
{
EnterCriticalSection(&h_section);
if(ticket>0)
{
Sleep(1);
cout<<"thread 2:"<<ticket--<<endl;
}
else
break;
LeaveCriticalSection(&h_section);
}
return 0;

}
...全文
872 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-09-13
  • 打赏
  • 举报
回复
《Windows核心编程》
homesos 2017-09-13
  • 打赏
  • 举报
回复
引用 3 楼 lwj1861 的回复:
[quote=引用 1 楼 homesos 的回复:] 把 InitializeCriticalSection(&h_section); 放在最前,先调用这个初始化,再调用CreateThread。 CloseHandle的使用没有问题。
InitializeCriticalSection(&h_section); HANDLE hd2; HANDLE hd1; 这样是正常了,但是我看孙鑫老师那个教程,他当年运行就没问题,难道是因为他用的是win2000[/quote] 孙鑫的教程讲的挺好的,不过教学归教学,实际应用归实际应用,就像很多名师的书没有遵循基本的编程规范一样,这个跟多核时序有关,理论上是要先初始化好各种环境,再开始启动逻辑,这段代码单核下应该没问题,多核下就有很大的隐患了,启动了线程,线程已经在运行用锁了,此时锁初始化的代码还没走到,有点类似的问题我以前在开源项目中遇到过一次,是取CPU时间,单核下取的CPU时间是顺序的,多核下如果没指定取哪个核的时间,就会乱掉,一会取CPU1的时间,一会取其他CPU的时间,有时候时间差就会变成负值,导致经常崩溃,后来改了它的源代码指定到一核的CPU就正常了。
l357630798 2017-09-13
  • 打赏
  • 举报
回复
你如果使用CREATE_SUSPENDED标志创建线程,然后等InitializeCriticalSection(&h_section); 语句之后,再执行ResumeThread应该也是没问题的。 问题就在于InitializeCriticalSection还没初始化,你创建的线损已经开始运行了。
l357630798 2017-09-13
  • 打赏
  • 举报
回复
引用 1 楼 homesos 的回复:
把 InitializeCriticalSection(&h_section); 放在最前,先调用这个初始化,再调用CreateThread。 CloseHandle的使用没有问题。
+1
zgl7903 2017-09-13
  • 打赏
  • 举报
回复
引用 3 楼 lwj1861 的回复:
[quote=引用 1 楼 homesos 的回复:] 把 InitializeCriticalSection(&h_section); 放在最前,先调用这个初始化,再调用CreateThread。 CloseHandle的使用没有问题。
InitializeCriticalSection(&h_section); HANDLE hd2; HANDLE hd1; 这样是正常了,但是我看孙鑫老师那个教程,他当年运行就没问题,难道是因为他用的是win2000[/quote] 可能以前是单核系统, 在线程还没运行时InitializeCriticalSection已经执行完了, 现在是多核系统,线程启动的很快 反正从正常逻辑上讲也是应该先初始化再启动线程
oyljerry 2017-09-12
  • 打赏
  • 举报
回复
创建线程马上就关闭句柄这是不正确的做法,你应该在线程结束以后再关闭
一线贫民_ 2017-09-12
  • 打赏
  • 举报
回复
引用 1 楼 homesos 的回复:
把 InitializeCriticalSection(&h_section); 放在最前,先调用这个初始化,再调用CreateThread。 CloseHandle的使用没有问题。
InitializeCriticalSection(&h_section); HANDLE hd2; HANDLE hd1; 这样是正常了,但是我看孙鑫老师那个教程,他当年运行就没问题,难道是因为他用的是win2000
homesos 2017-09-11
  • 打赏
  • 举报
回复
把 InitializeCriticalSection(&h_section); 放在最前,先调用这个初始化,再调用CreateThread。 CloseHandle的使用没有问题。

15,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧