java线程条件变量_多线程系列之四 条件变量(简单模型理解条件变量) | 学步园...

有时候负责数据读取的线程获得资源访问权后发现没有资源可以读取,或者写入线程在获得资源访问权的时候发现并没有数据可写或是当前的数据结构已满在等待处理的时候,我们希望线程可以释放掉锁,并进入睡眠状态,直到得到通知已经有数据可读或可写为止。这听起来确实很酷,因为无事可做的线程将不再占用(或占用很少的)cpu周期。

BOOL WINAPI SleepConditionVariableCS(

__inout PCONDITION_VARIABLE ConditionVariable,

__inout PCRITICAL_SECTION CriticalSection,

__in DWORD dwMilliseconds

);

BOOL WINAPI SleepConditionVariableSRW(

__inout PCONDITION_VARIABLE ConditionVariable,

__inout PSRWLOCK SRWLock,

__in DWORD dwMilliseconds,

__in ULONG Flags

);

这两个函数可以实现以上的功能。第一个参数是初始化的条件变量,调用的线程将等待这个条件变量。第二个条件为指向一个关键段或SRWLock的指针,指向已经初始化了的变量。第三个参数是等待的时间。SleepConditionVariableSRW可以指定得到锁的方式为独占或是共享,通过传入CONDITION_VARIABLE_LOCKMODE_SHARED表示以共享的方式获得锁,传入0表示以独占的方式获得锁。

VOID WINAPI WakeConditionVariable(

__inout PCONDITION_VARIABLE ConditionVariable

);

VOID WINAPI WakeAllConditionVariable(

__inout PCONDITION_VARIABLE ConditionVariable

);

这两个函数用来唤醒等待条件而睡眠的线程。WakeAllConditionVariable可以唤醒多个线程。

VOID WINAPI InitializeConditionVariable(

__out PCONDITION_VARIABLE ConditionVariable

);

这个函数初始化条件变量。

用一个简单的程序来说明整个流程。

1336904024_2833.png

写入线程代码:

DWORD WriteProc(LPVOID lp)

{

while(InterlockedCompareExchange(&bStop,1,1) != 1)

{

AcquireSRWLockExclusive(&srwLock);

if (ivec.size() == 10)//数组已经满了,睡眠等待读取线程的处理

{

SendDlgItemMessage(hMain,IDC_LIST_WRITE,LB_ADDSTRING,NULL,(LPARAM)L"写入线程--数组已满,等待。");

SleepConditionVariableSRW(&cvToWriteFile,&srwLock,INFINITE,0);

}

for (int i = 0;i < 10;++i)

{

int iNum = rand();

ivec.push_back(iNum);

}

//写文件

ofstream os(fileName.c_str());

copy(ivec.begin(),ivec.end(),ostream_iterator(os," "));

os.close();

SendDlgItemMessage(hMain,IDC_LIST_WRITE,LB_ADDSTRING,NULL,(LPARAM)L"写入线程--写文件完成。");

WakeConditionVariable(&cvToRead);//处理完成,唤醒读取线程

ReleaseSRWLockExclusive(&srwLock);

Sleep(100);

}

return 0;

}

读取线程代码:DWORD ReadProc(LPVOID lp)

{

while(InterlockedCompareExchange(&bStop,1,1) != 1)

{

AcquireSRWLockShared(&srwLock);

if (ivec.empty())//数组为空,睡眠等待写入数据

{

SendDlgItemMessage(hMain,IDC_LIST_READ,LB_ADDSTRING,NULL,(LPARAM)L"读取线程--数组为空,等待。");

SleepConditionVariableSRW(&cvToRead,&srwLock,INFINITE,CONDITION_VARIABLE_LOCKMODE_SHARED);

}

if (ivec.size() == 10)

{

for(;ivec.empty() == false;)

{

ivec.pop_back();

}

SendDlgItemMessage(hMain,IDC_LIST_READ,LB_ADDSTRING,NULL,(LPARAM)L"读取线程--清空数组完成。");

if(DeleteFileA(fileName.c_str()))

SendDlgItemMessage(hMain,IDC_LIST_READ,LB_ADDSTRING,NULL,(LPARAM)L"读取线程--删除文件完成。");

WakeConditionVariable(&cvToWriteFile);//操作完成,唤醒写入线程

}

ReleaseSRWLockShared(&srwLock);

Sleep(100);

}

return 0;

}

程序运行截图:

1336904162_4829.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值