有两个线程A和B,由于某种原因,打算使用Suspend和Resume来实现两个线程的同步。\\
设置一个全局标志位g_bFlag,和一个全局的CRITICAL_SECTION,A线程若检测到该g_bFlag为True,则Resume线程B,若该g_bFlag为Fals,则Suspend自身,等待B线程来Resume它。同样,B也进行这样的操作。开始线程跑的不错,但是经过若干次以后,A和B线程都会Suspend。\\
ps:对g_bFlag的访问和修改都使用了CRITICAL_SECTION来包含,并且将g_bFlag申明成了volatile bool。为什么会出线这样的情况呢?
设置一个全局标志位g_bFlag,和一个全局的CRITICAL_SECTION,A线程若检测到该g_bFlag为True,则Resume线程B,若该g_bFlag为Fals,则Suspend自身,等待B线程来Resume它。同样,B也进行这样的操作。开始线程跑的不错,但是经过若干次以后,A和B线程都会Suspend。\\
ps:对g_bFlag的访问和修改都使用了CRITICAL_SECTION来包含,并且将g_bFlag申明成了volatile bool。为什么会出线这样的情况呢?
用对象事件,或信号量等;方法很多。
{
....
bool bStatu = g_bFlag;
EnterCriticalSection(..);
g_bFlag ^= TRUE;
LeaveCriticalSection(...); if( bStatu )
{
Resume(ThreadB);
}
else
{
Suspend(Me);
}
...
}请问LZ是这样的吗?记住:顺序一定不能搞反了。另外为什么要内部定义一个变量来保存你的全局变量,自己想一下吧!初步估计你是在挂起自己之前,没有释放临界区(即是先Suspend,后LeaveCriticalSection),导致另一个线程无法修改全局变量,从而也无法唤醒另一个线程。
EnterCriticalSection(&g_CS);
if (!g_bFlag)
{
m_thread_statue = suspend;
::LeaveCriticalSection(&g_CS);
SuspendThread(m_hThread);
m_thread_statue = running;
}
else
{
g_bFlag = true;
::LeaveCriticalSection(g_CS);
ResumeThread(pThreadB->m_hThread);
}ThreadB的代码和ThreadA的代码一致。
我解释一下为什么不打算使用同步对象。是由于一旦WaitSingleObject(hEvent,500),在这500ms里面,OS不会释放对Thread的占用,而且CPU的占用率也较高,使用SuspendThread会使OS立刻切换线程。Fiber没有用过,所以没有使用Fiber。
EnterCriticalSection(&g_CS);
if (!g_bFlag)
{
m_thread_statue = suspend;
::LeaveCriticalSection(&g_CS);
SuspendThread(m_hThread);
m_thread_statue = running;
}
else
{
g_bFlag = true;
::LeaveCriticalSection(g_CS);
ResumeThread(pThreadB->m_hThread);
}
[/code]
[code = {0}]
EnterCriticalSection(&g_CS);
if (!g_bFlag)
{
m_thread_statue = suspend;
::LeaveCriticalSection(&g_CS);
SuspendThread(m_hThread);
m_thread_statue = running;
}
else
{
g_bFlag = true;
::LeaveCriticalSection(g_CS);
ResumeThread(pThreadB->m_hThread);
}
[/code]
if (!g_bFlag)
{
// 这里假的时候,为什么不设为真让另一线程来唤醒自己?g_bFlag = TRUE;
m_thread_statue = suspend;
::LeaveCriticalSection(&g_CS);
SuspendThread(m_hThread); // 是否应与下面一句交换次序?
m_thread_statue = running;
}
else
{
g_bFlag = true; // 已经为TRUE了,这里为什么还要设为TRUE?是否应该为FALSE? g_bFlag = FALSE;
::LeaveCriticalSection(g_CS);
ResumeThread(pThreadB->m_hThread);
} 贴代码先选中你的代码,然后点击编辑框上的带“#”的图标,选择你的代码语言就可以了。或者在你的代码前后用..括起来。
WaitSingleObject就是放弃CPU时间,怎么可能导致CPU使用率过高呢?
如果多个任务同一时间只有一个在运行,用Fiber是最合适的了,Fiber就是为这种情况设计的。
EnterCriticalSection(&g_CS);
if (!g_bFlag)
{
g_bFlag = true;
m_thread_statue = suspend;
::LeaveCriticalSection(&g_CS);
SuspendThread(m_hThread); // 是否应与下面一句交换次序?
m_thread_statue = running;
}
else
{
g_bFlag = false;
::LeaveCriticalSection(g_CS);
ResumeThread(pThreadB->m_hThread);
}
“WaitSingleObject就是放弃CPU时间”,对于这点我不甚理解,因为没有文档可循。我只知道在Event被Trigger的情况下,等待的线程可以获得CPU的调度机会。
14楼的,Suspend都是自己suspend自己,而不是由外界进行Suspend操作,另外在自己suspend自己之前都会有LeaveCriticalSection的操作。
ps:我已经将Flag都打印出来了,打印出来的结果都是一致的……郁闷。
EnterCriticalSection(&g_CS);
if (!g_bFlag)
{
g_bFlag = true;
m_thread_statue = suspend;
::LeaveCriticalSection(&g_CS);
SuspendThread(m_hThread);
m_thread_statue = running;
}
else
{
g_bFlag = false;
::LeaveCriticalSection(g_CS);
ResumeThread(pThreadB->m_hThread); //你怎么知道每个线程判断当g_bFlag为true时,都要终止线程B呢?
}1.假设一开始线程A开始,线程B暂停,那么,当线程A运行到
ResumeThread(pThreadB->m_hThread);
时,A与B线程同时开始,但g_bFlag为false,A的下一循环会进入到
EnterCriticalSection,而B线程也会进入到EnterCriticalSection,究竟哪一个先进入EnterCriticalSection没有定数,
2.万一线程A先入EnterCriticalSection,那么线程B被暂停。
此时线程A执行第一个if条件,到语句
m_thread_statue = running
之后:
g_bFlag=true,A线程暂停,
3.B线程因为A线程运行到LeaveCriticalSection而继续。
线程B根据g_bFlag条件,执行语句第二条if语句块。重新把自己启动。
4.当线程B再次进入到EnterCriticalSection之后,g_Flag为false,执行到SuspendThread就把自己给暂停了,
结果两个线程都被暂停。设置两个线程句柄与两个线程过程,SuspendThread与ResumeThread要操作的对象要区分开来。
线程A,暂停线程A,启动线程B
线程B,暂停线程B,启动线程A
1.EnterCriticalSection的时候只会有一个Thread进入,另外一个Thread会等前一个线程LeaveCriticalSection才进入;
2.进入EnterCriticalSection的线程会先看看flag,如果flag不为true,那么就suspend自己,直到另外一个Thread Resume自己。
3.B任何线程Suspend自己之前都保证自身的状态被记录下来
你是否真的为每个线程设置了各自的状态,我只看到一个g_bFlag,这个变量好像是全局的.你是否为每个线程区分地定义了各自的状态.
void CProjectFrame::AssertValid() const
{
CMDIChildWnd::AssertValid();
}