信号灯计数在调试与运行时的表现有所不同(200分)

  • 主题发起人 主题发起人 ygyu
  • 开始时间 开始时间
Y

ygyu

Unregistered / Unconfirmed
GUEST, unregistred user!
描述:
1:首先创建初始计数为0的Semaphore
hSem = CreateSemaphore(NULL, 0, 10, NULL);
2:启动线程等待该信号灯被释放
BeginThread(ThreadPorc, 0);
UINT ThreadProc(LPVOID pParam)
{
WaitForSingleObject(hSem, INFINITE);
}
3:ThreadProc线程启动后,在主线程中通过释放信号灯来结束该线程,
ReleaseSemaphore(hSem, 1, &nPrevCount)
4:紧跟着再次调用ReleaseSemaphore获得信号灯的计数值
ReleaseSemaphore(hSem, 1, &nPrevCount)

此时返回的信号灯应当为0,因为第一次调用
ReleaseSemaphore的时候有一个线程阻塞在该信号灯上,因而不会引起计数值的加一.
但是当使用Delphi4.0调试的时候,并且在第二个ReleaseSemaphore设置断点,则返回的计数值必定为1.
另外如果我们使用VC6.0(代码类似),如果断点在第二个ReleaseSemaphore处停留一会儿,然后单步运行该语句,则返回的计数值有时为1.
 
我猜想defei里的debug对多线程的支持不是很好(那确实很难),原来
并行执行的程序现在线性执行,变量的value肯定change。
另外,因为releasesemaphore无需独占semaphore对象,所以两次
releasesemaphore有可能都在WaitForSingleObject(hSem, INFINITE);
之前发生.
 
在VC中也是一样,但VC的调试器中也一样.
WaitForSingleObject是在Releasesemaphore之前
 
两次 ReleaseSemaphore(hSem, 1, &nPrevCount)
之间主线程的时间片未用完,所以子线程还得不到机会被激活运行

如果出现这种情况,主线程第一个ReleaseSemaphore(hSem, 1, &nPrevCount)
完成后刚好时间片用完了,子线程能得到机会运行,
当轮回来主线程运行第2个ReleaseSemaphore(hSem, 1, &nPrevCount)时
就会得到你上面想要的结果,不过机会很小.
 
主线程的2个ReleaseSemaphore(hSem, 1, &nPrevCount)
之间放一行:Sleep(0) (放弃当前的时间片,让其他同等级线程运行)
可能能达到你想要的效果
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
913
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部