您的位置:首页 > 运维架构 > Linux

Linux学习之"使条件变量互斥量避免无限等待"

2011-10-22 12:34 459 查看
View Code

#include <iostream>
#include <unistd.h>
#include "CLThread.h"
#include "CLExecutiveFunctionProvider.h"
#include "CLMutex.h"
#include "CLCriticalSection.h"
#include "CLConditionVariable.h"

using namespace std;

struct SPara
{
CLConditionVariable condition;
CLMutex mutex;
volatile int flag;
};

class CLMyFunction : public CLExecutiveFunctionProvider
{
public:
CLMyFunction()
{
}

virtual ~CLMyFunction()
{
}

virtual CLStatus RunExecutiveFunction(void *pContext)
{
SPara *p = (SPara *)pContext;

{
CLCriticalSection cs(&(p->mutex));

p->flag = 1;
}

p->condition.Wakeup();

return CLStatus(0, 0);
}
};

int main()
{
SPara *p = new SPara;
p->flag = 0;

CLExecutiveFunctionProvider *myfunction = new CLMyFunction();
CLExecutive *pThread = new CLThread(myfunction);
pThread->Run((void *)p);

{
CLCriticalSection cs(&(p->mutex));

while(p->flag == 0)
p->condition.Wait(&(p->mutex));
}

pThread->WaitForDeath();

cout << "in main thread" << endl;

delete pThread;
delete myfunction;
delete p;

return 0;
}


这个程序理想顺序是主线程先进入临界区,然后执行p->condition.Wait(&(p->mutex))释放互斥锁并在条件变量上等待;接着子线程进入临界区把flag置1,而后退出临界区,最后唤醒主线程,使其继续运行。

主线程中,临界区为从”CLCriticalSection cs(&(p->mutex))“开始,到主线程被挂起为止;子线程中,临界区为从“CLCriticalSection cs(&(p->mutex))”到p->flag被赋值为1结束。

当主线程先进入临界区时,此时主线程已经被挂起,而子线程的唤醒尚未执行,故不会产生无限等待。

当子线程先进入临界区时,此时p->flag被置1,而主线程对p->flag的判断尚未执行,故主线程不会再等待条件变量。

等待线程的执行顺序:

调用pthread_mutex_lock

While(判断条件)pthread_cond_wait(while判断等待条件是由于线程可能不是被pthread_cond_signal唤醒,可能是由信号等唤醒(futex))

调用pthread_mutex_unlock

被等待线程

调用pthread_mutex_lock

修改条件

调用pthread_mutex_unlock

调用pthread_mutex_broadcast等
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: