线程互斥中双线程对资源按序访问的方法

2017-01-12 19:04:22来源:cnblogs.com作者:NikoLeo人点击

各种多线程同步(互斥)方法中,线程访问共享资源顺序是不确定的。当线程A必须在线程B之后访问数据资源R时,用如下方法可以实现。

//互斥量,表示线程对数据资源的操作生效
HANDLE ghValidA= CreateEvent(NULL, TRUE, FALSE, NULL);
HANDLE ghValidB= CreateEvent(NULL, TRUE, TRUE, NULL); //参数2,手动重置;参数3,初始值。两个互斥量不能同为FALSE,否则会死锁,A为FALSE,B为TRUE,则线程A先进入,之后两线程就可以循环依次进入了

void main()
{
//线程A和线程B
HANDLE hThreadA= CreateThread(NULL, 0, ThreadA, NULL, 0, NULL);
HANDLE hThreadB= CreateThread(NULL, 0, ThreadB, NULL, 0, NULL);
}

DWORD WINAPI ThreadA(LPVOID p)
{
while(1)
{
//等待线程B的数据有效
if( WaiteForSingleObject(ghValidB, 10)==WAITE_OBJECT_0 )
{
ResetEvent(ghValidA); //置 线程A的数据无效
DoSthA( );//操作数据
ResetEvent(ghValidB); //置 线程B的数据无效,因为A操作后,需要等B给予新数据。若没有这一步,线程会立即进入下一次Wait循环,导致死锁
SetEvent(ghValidA); //置线程A数据有效
}
}
}

DWORD WINAPI ThreadB(LPVOID p)
{
while(1)
{
if( WaiteForSingleObject(ghValidA, 10)==WAITE_OBJECT_0 )
{
ResetEvent(ghValidB);
DoSthB( );
ResetEvent(ghValidA);
SetEvent(ghValidB);
}
}
}

遇到上述问题的背景是,线程A为数据处理线程,线程B为采集卡线程,B实际上不是循环,而是由采集卡的驱动程序回调。线程B触发频率远高于线程A处理频率,且线程B的回调函数若不返回,则会阻塞新的数据帧。因此在DoSthB中将数据拷贝出来(即资源R),在DoSthA中处理数据。这样,线程A处理的始终是最新数据,而不会阻塞线程B的数据刷新;在线程A处理过程中到达的数据会被丢弃。


最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台