CRITICAL_SECTION的运用(现在debug时出的汗,都他妈是当年亲手写下它时脑子里进的水!)

被自己的愚蠢与鲁莽坑了无数次后,开始明白一个道理。不管多灵异的bug,都不会是复杂到让你无法理解的。至少大多数时候是这样的……


CRITICAL_SECTION是Windows下定义的一个结构体,作用就是字面意思,临界区。


这个临界区指的是在 EnterCriticalSection与LeaveCriticalSection中间的这一段代码为临界区。比如你有好几个线程都要使用几个临界资源,可以把对临界资源的全部操作都放入临界区中,使线程同步。


注意:一定要把所有对临界资源的操作都要放入临界区域内。否则很有可能会造成各种奇怪的死锁。


CRITICAL_SECTION的作用其实并不是锁定资源,而是“锁定代码”。即不同的线程只能有一个在CRITICAL_SECTION中,不可重入。当已经有其他线程EnterCriticalSection时,当前线程必须等待,直到该线程LeaveCriticalSection。


比如:


thread1()

{

    EnterCriticalSection(&lock);

    //do nothing

    //Sleep(10000);

    LeaveCriticalSection(&lock);

}


thread2()

    EnterCriticalSection(&lock);

    //do something

     ……

    LeaveCriticalSection(&lock);

}

当线程一进入临界区时什么都不做,并不操作任何临界资源。线程二依然要等线程离开临界区才能进入临界区操作临界资源。因为CRITICAL_SECTION的作用其实并不是锁定资源,而是“锁定代码”。


今天调试出了一个“历史遗留BUG”,老板的项目中有三个以下三个线程要进行同步。

线程一:从照相机中读取数据放入buffer中。

线程二:从buffer中读取数据并显示。

线程三:从buffer中读取数据做计算处理。(因为要求实时显示,线程三中的数据处理没有那么快的速度,所以干脆分成两个线程)。


功能一:仅仅显示数据,而不做数据处理,即线程一与线程二同步。这个时候程序完全没有问题显示的很好。

功能二:显示并处理数据,三线程进行同步。这个时候也貌似没有问题。

然后再使用功能一,发现死锁了。在线程二进入临界区时无限等待。

重新使用功能二,依然没有问题,只是不能再使用功能一了。


之前总感觉非常的诡异,总以为是线程二的实现出了什么问题。今天仔细的把线程三的实现好好的检查了一遍,发现读取buffer的语句竟然没有放在EnterCriticalSection与LeaveCriticalSection之间,真不知道当时写下这段代码的时候在想什么……


虽然找到问题的所在了,但是对于问题是如何发生的还是理解的不够清晰。以后想清楚了具体是怎么回事再更新吧,反正现在是真的了解了对临界资源的操作一定要放在临界区中!不然真的后果很惨痛。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值