问个问题,有关线程的挂起
想和大家交流下:一个线程把自己挂起,然后等满足一些条件再由别的线程把它唤醒。
这些一般使用ace的什么呢?
我用了ACE_Condition<ACE_Thread_Mutex>:
创建了一对ACE_Thread_Mutex和ACE_Condition,挂起的时候先锁住、在调wait;唤醒的时候也锁、然后signal:
挂起:
st.pMutex->acquire();
st.pCondition->wait();
st.pMutex->release();
唤醒:
st.pMutex->acquire();
st.pCondition->signal();
st.pMutex->release();
可是很偶尔提示唤醒成功了,但是被挂起线程仍然没有继续向下走。不知这会是什么原因。
ACE_Thread_Manager::instance()->suspend(thid);用这个不能把自己挂起,resume的时候唤不醒,这只能用于挂起别的线程。 个人之见,还是OS决定的线程调度,ACE只是调用了API。所以,我觉得应该是正常的。 楼主代码,signal的时候永远不会有线程在wait,反之亦然 sorry,上面说错了
wait实际上是一个原子操作,包括2个动作:
1,wait , block
2,释放该条件变量对应的mutex
在wait返回时,自动重新获得该mutex,如果不能获得是不会返回的
所以在唤醒的时候,一定要先release,再signal ace很多例子里面用mutex和condition都是用ACE_GUARD_RETURN,加上这个宏,其实就是锁住然后wait、锁住然后signal。 汗。。。仔细看了下第一册书和APUE的内容,都只是提到wait返回后一定是重新获得了lock的,但是并没有说如果另一线程发signal或broadcast时如果并没有释放锁,会怎么样。
ACE的示例程序是用的guard,但是下面这种情况会怎么样呢?
挂起等待:
{
ACE_Guard<ACE_Thread_Mutex> guard(lock);
condition.wait();
}
通知唤醒:
{
ACE_Guard<ACE_Thread_Mutex> guard(lock);
condition.signal();
ACE_OS::sleep(2);
}
[ 本帖最后由 wishel 于 2008-11-24 20:10 编辑 ] 我写了个测试程序测了下,两个线程分别是:
ACE_Thread_Mutex lock;
ACE_Condition_Thread_Mutex condition(lock);
DWORD waitCondition(void*) {
ACE_Guard<ACE_Thread_Mutex> guard(lock);
cout << "begin wait" << endl;
condition.wait();
cout << "wait over" << endl;
return 0;
}
DWORD signalCondition(void*) {
ACE_OS::sleep(2); // 保证wait先执行
ACE_Guard<ACE_Thread_Mutex> guard(lock);
cout << "begin signal" << endl;
condition.signal();
cout << "begin sleep" << endl;
ACE_OS::sleep(2); // 模拟耗时较长的任务
cout << "sleep over" << endl;
return 0;
}
int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) {
ACE_Thread_Manager::instance()->spawn(waitCondition);
signalCondition(0);
ACE_Thread_Manager::instance()->wait();
return 0;
}
结果:
begin wait
begin signal
begin sleep
sleep over
wait over
可以看到,只有signal线程运行结束,打印出sleep over后,wait线程的wait才获得lock并返回,虽然早就收到signal了
[ 本帖最后由 wishel 于 2008-11-24 20:08 编辑 ] 楼主程序的问题可能是没控制2个线程的执行次序,signal线程先运行了,然后wait线程就没人唤醒了。
页:
[1]