找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 6971|回复: 7

问个问题,有关线程的挂起

[复制链接]
发表于 2008-11-21 13:23:07 | 显示全部楼层 |阅读模式
想和大家交流下:
一个线程把自己挂起,然后等满足一些条件再由别的线程把它唤醒。
这些一般使用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的时候唤不醒,这只能用于挂起别的线程。
发表于 2008-11-21 22:44:44 | 显示全部楼层
个人之见,还是OS决定的线程调度,ACE只是调用了API。所以,我觉得应该是正常的。
发表于 2008-11-22 09:21:21 | 显示全部楼层
楼主代码,signal的时候永远不会有线程在wait,反之亦然
发表于 2008-11-23 00:24:25 | 显示全部楼层
sorry,上面说错了
wait实际上是一个原子操作,包括2个动作:
1,wait , block
2,释放该条件变量对应的mutex
在wait返回时,自动重新获得该mutex,如果不能获得是不会返回的

所以在唤醒的时候,一定要先release,再signal
 楼主| 发表于 2008-11-24 11:07:38 | 显示全部楼层
ace很多例子里面用mutex和condition都是用ACE_GUARD_RETURN,加上这个宏,其实就是锁住然后wait、锁住然后signal。
发表于 2008-11-24 20:00:02 | 显示全部楼层
汗。。。仔细看了下第一册书和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 编辑 ]
发表于 2008-11-24 20:06:19 | 显示全部楼层
我写了个测试程序测了下,两个线程分别是:
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 编辑 ]
发表于 2008-11-24 20:07:32 | 显示全部楼层
楼主程序的问题可能是没控制2个线程的执行次序,signal线程先运行了,然后wait线程就没人唤醒了。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-22 16:43 , Processed in 0.026477 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表