您的位置:首页 > 其它

不使用系统API来实现互斥保护功能

2008-04-02 14:45 477 查看
一般临界资源的互斥保护,需要使用类似take_mutex / give_mutex 类似的系统API来实现,

一般需要从用户空间切换到内核空间,有时候可能要关中断等,为了实现一个开销小的,

实现简单的临界资源的互斥保护机制,我设计了一个方法,希望大家能参考一下,给点建议。

volatile int a = 0;

volatile int b = 0;

/* 线程 A */

void thread_A()
{
while ( 1 ) {
a++;
if ( b == 0 ) {
access_the_critical_resource;
a = 0;
break;
} else {
a = 0;
}
}
}

/* 线程 B */

void thread_B()
{
while ( 1 ) {
b++;
if ( a == 0 ) {
access_the_critical_resource;
b = 0;
break;
} else {
b = 0;
}
}
}

现在来分析一下为什么这两个线程能实现互斥,

A线程首先将a加1,然后去加查b变量,如果b为0,说明B线程还没有将b加1,或者是B线程已经将b加1,但还没有写回到内存。总之B线程还运行在b++语句之前的某个位置,或者是刚执行完b=0的操作(即运行在b=0与b++之间的某个位置),所以我们断定B此时没有进入临界区,故A线程可以执行后面的临界区访问操作。

那么如果但A线程检查b变量时,如果b变量不等于0,那么此时B线程有可能在访问临界区,也有可能只是执行完了b++语句,但还没有进入临界区,此时A线程通过if ( b == 0 )的判断来避免了与B同时进入临界区的危险。

再分析,因为A线程在尝试进入临界区之前会将自己的开关变量a加1,所以一旦A互斥检查获得通过的话(if ( b == 0 )),就说明自己可以放心进入临界区了,因为此时可以肯定对方运行在b = 0;

与 b++;这两条语句之间,而不是b++与b=0之间(请注意这两条语句的先后顺序),所以当A进入了临界区,并处在临界区的这段时间内,B会被 if ( a == 0 )这个条件阻挡在临界区外,直到A出了临界区,执行a=0;break;,

此时B才有可能进入到临界区。

根据对称性,把A和 B反过来分析也一样,当然这种方法有很多缺点,比如极端情况下两个线程有可能都进不了

临界区等,我这里就不一一列举了,仅仅做个试验尝试而已。

在SMP的环境中,这种方法应该也可以,不会有逻辑错误。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐