不使用系统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的环境中,这种方法应该也可以,不会有逻辑错误。
一般需要从用户空间切换到内核空间,有时候可能要关中断等,为了实现一个开销小的,
实现简单的临界资源的互斥保护机制,我设计了一个方法,希望大家能参考一下,给点建议。
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的环境中,这种方法应该也可以,不会有逻辑错误。
相关文章推荐
- c#不使用系统api实现可以指定区域屏幕截屏功能
- 使用 Spring Boot 2.0 + WebFlux 实现 RESTful API功能
- java开发系统内核:使用一个中断实现多个API调用
- 使用 HTML5 webSocket API实现即时通讯的功能
- SpringMVC(21):使用springmvc+spring+jdbc 优化订单管理系统的示例(ID查看供应商信息明细-REST的功能实现)
- Android使用系统自带的相机实现一键拍照功能
- 使用EF6和MVC5实现一个简单的选课系统--使用EF6实现基本的GRUD功能(2/12)
- 玩转nodeJS系列:使用原生API实现简单灵活高效的路由功能(支持nodeJs单机集群),nodeJS本就应该这样轻快
- 使用js实现显示系统当前时间并实现倒计时功能并触发模态框(遮罩)功能
- Linux C系统编程:使用线程池,实现cp功能
- 用linux系统API实现定时器功能
- 使用系统api实现数据库的增、删、改、查
- SpringMVC(24):使用springmvc+spring+jdbc 优化订单管理系统的示例(多文件上传功能的实现)
- linux下使用系统调用编程实现copy命令功能
- Win8.1系统如何使用IE跟踪保护功能去除网页广告 使用IE跟踪保护功能屏蔽网页广告的设
- 使用系统api实现数据库的增、删、改、查
- 使用.net core ABP和Angular模板构建博客管理系统(实现编辑页面功能)
- 使用JAVA的开源API-JExcelAPI来操作Excel,实现基本的功能
- 字符串处理是许多程序中非常重要的一部分,它们可以用于文本显示,数据表示,查找键和很多目的.在Unix下,用户可以使用正则表达式的强健功能实现这些 目的,从Java1.4起,Java核心API就引入了java.util.regex程序包,它是一种有价值的基础
- android自定义View实现裁剪图片功能,不使用系统的