5392|13

74

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

100分求助:临界区的问题 [复制链接]

各位高手好:

我先说说我对临界区的理解:
   临界区代码段中维护了一些跟硬件或者中断相关的资源
   这些资源可能在同一进程中调用多次,所以需要用临界区把保护的代码框起来
如:
EnterCriticalSection(&(pHWHead->RegCritSec))
   被保护代码
LeaveCriticalSection(&(pHWHead->RegCritSec))
当第一个运行到临界区的代码(所有临界区代码哪个先进入哪个后进入无所谓)
占用此资源,当用完了LeaveCriticalSection释放给别的代码段用

而参数(&(pHWHead->RegCritSec))的定义为:在结构体S2410_UART_INFO中
        CRITICAL_SECTION         RegCritSec
我看的资料上写EnterCriticalSection的参数指向CRITICAL_SECTION的结构指针

问题:这个参数跟我的临界区有什么关系吗?

我看串口程序中定义了两个指向CRITICAL_SECTION的结构指针
分别为:    CRITICAL_SECTION        TransmitCritSec;
           CRITICAL_SECTION        RegCritSec;
临界区分别为:
         EnterCriticalSection(&(pHWHead->TransmitCritSec));
        EnterCriticalSection(&(pHWHead->RegCritSec));


        FifoModeReg = INREG(pHWHead, rUFCON);

        try {
                rFifoStat = INREG(pHWHead,rUFSTAT);
                TxFifoCnt = ((rFifoStat & SER2410_FIFOCNT_MASK_TX) >> 4);

                if (pHWHead->UseIrDA)
                {
                        // IR is half-duplex.
                        pHWHead->RxDiscard = TRUE;
                        DisEnSubINT(pHWHead, pHWHead->bRxINT);
                }
                    程序太长中间省略了很多
                                        // Enable xmit intr. We need to do this no matter what,
                // since the MDD relies on one final interrupt before
                // returning to the application.
                ClearPendingInts( pHWHead );

                EnINT(pHWHead, pHWHead->bINT);
                EnSubINT(pHWHead, pHWHead->bTxINT);
                pHWHead->fSW_EnTxINT = TRUE;  // FALSE;
        }
        except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
               
        }
        LeaveCriticalSection(&(pHWHead->RegCritSec));
        LeaveCriticalSection(&(pHWHead->TransmitCritSec));


1、这两个临界区定义的参数有什么区别,在程序中分别扮演什么角色?
2、EnterCriticalSection(&(pHWHead->RegCritSec))
   被保护代码
LeaveCriticalSection(&(pHWHead->RegCritSec))
当第一个运行到临界区的代码(所有临界区代码哪个先进入哪个后进入无所谓
这句话是我理解的,不知道是不是这么回事

最新回复

学习了  详情 回复 发表于 2008-11-10 13:25
点赞 关注

回复
举报

78

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
问题2可能没问清楚:

我理解:
一些可能被多处调用的资源需要被如下保护起来:
EnterCriticalSection(&(pHWHead->RegCritSec))
  被保护代码
LeaveCriticalSection(&(pHWHead->RegCritSec))

当第一个运行到临界区的代码占用此资源,(所有临界区代码哪个先进入临界区哪个后进入临界区无所谓,没有哪个必须先进入哪个后进入之分)
当用完了LeaveCriticalSection释放给别的代码段用
这个是我理解的
请问是否正确,特别是红字的部分
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
EnterCriticalSection
只是一个api。

它的参数指明了当前要进入的是哪个临界区,也就是说要开始保护哪个资源了。
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(高级)

4
 
开始保护哪个资源了???
你指的这个被保护的资源!=  EnterCriticalSection和LeaveCriticalSection之间被保护的代码吗???
即:EnterCriticalSection(&(pHWHead->RegCritSec))
      被保护代码
     LeaveCriticalSection(&(pHWHead->RegCritSec))
如果相等,没看出这两个有什么联系啊??
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

5
 
也就是说
这个参数(&(pHWHead->RegCritSec)) 与
EnterCriticalSection(&(pHWHead->RegCritSec))
     .....
LeaveCriticalSection(&(pHWHead->RegCritSec))

之间的被保护的代码有什么关系???

 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

6
 
是为
EnterCriticalSection(&(pHWHead->RegCritSec))
    .....
LeaveCriticalSection(&(pHWHead->RegCritSec))

之间被保护的代码开辟一个临界区(内存空间)的意思吗???
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

7
 
楼主可以这样理解,就就是说同一时间只能有一个线程访问EnterCriticalSection(&(pHWHead->RegCritSec))
    .....
LeaveCriticalSection(&(pHWHead->RegCritSec))之间的代码.
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

8
 
我尝试一下来这样来解释,哈哈,

你有一样宝贝人人都想来见识一下,可是为了安全一个时间段只能允许一个人来瞻仰,
这个时候你需要请一个保镖,这个保镖很好帮你保护你的宝贝:当大家都抢在门口等着要看你宝贝的时候,他来确保一个一个的人进来看。
当然进来的时候保镖确认一下,出去的时候再确认一下。
一个保镖一个宝贝,也可以多个保镖一个宝贝。

就是这样啦:
EnterCriticalSection();//保镖确认
受保护的代码                //宝贝可以被瞻仰了
LeaveCriticalSection();//保镖再确认,这样下一个人就可以来看你的宝贝啦。

 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

9
 
呵呵
非常感谢
那别人具备什么条件保镖才能让别人瞻仰我的宝贝??
还是这个不需要我管了,
由保镖的脑袋(系统)自己做主??
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

10
 
保护的资源可能是一个变量,一个硬件资源,一个文件,等等,
一个共性是:如果被同时访问可能造成代码出错。

EnterCriticalSection();//
LeaveCriticalSection();//

只是为了保护那个资源。而不是里面的全部代码。
里面的代码只是在使用那个资源。

例子:

int g_iGlobal;  //这是一个全局的变量,是一个公用资源
CRITICAL_SECTION g_csCritSec; //定义一个临界区保护该资源

。。。。。
初始化g_csCritSec;
。。。。。
线程A:

EnterCriticalSection(&g_csCritSec);//
if(1 == g_iGlobal)                //
{
   int i = g_iGlobal * 100;
}
else if( 2 == g_iGlobal)
{
   int i = g_iGlobal * 200;
}
LeaveCriticalSection(&g_csCritSec);//

线程B:

EnterCriticalSection(&g_csCritSec);//
if(1 == g_iGlobal)                //
{
   g_iGlobal = 2;
}
else if( 2 == g_iGlobal)
{
   g_iGlobal = 1;
}
LeaveCriticalSection(&g_csCritSec);//


两个线程同时在跑。

为了防止A在
if(1 == g_iGlobal)成功后,但是在
int i = g_iGlobal * 100;
执行前,公共资源g_iGlobal被B修改,所以加入临界区来保护公共资源g_iGlobal。

 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

11
 
哈哈,这个我明白
感谢两位高手绞尽脑汁的帮我解释这个问题

可是我就是想知道

1.是不是线程A和线程B谁先占用这个临界区资源都无所谓
  不象waitforsingleobject(...)必须等待事件被使能才可以象下运行

2.(&g_csCritSec)这个东西是给需要保护的代码(如:int i = g_iGlobal * 100; )
    开辟一个在LeaveCriticalSection之前不能被别人访问的房子??是这样吧
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

12
 
1. 临界区只保证共享资源在同一时间内被一个线程访问,并不能控制谁先谁后,所以不是什么时候都能用的
2. 就像你说的,CRITICAL_SECTION 只是用来告诉系统的,你创建了一个临界区,和你的代码没有什么关系

微软网站上有一篇 under the hood 的文章,对临界区有深入的解析
http://msdn.microsoft.com/zh-cn/magazine/cc164040(en-us).aspx
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

13
 

问题1:
pHWHead->RegCritSec 比如一个电话亭,

EnterCriticalSection(&(pHWHead->RegCritSec))
  被保护代码
LeaveCriticalSection(&(pHWHead->RegCritSec)) 两个之间的代码就像一个在电话亭里打电话的人。

这就说明了,同一时刻只能有一个人进电话亭打电话。

问题2:就像一个人取钱时,取款机这时只能他一个人用,同时为了别人偷看密码,其它人必须在黄线之外。那么黄线与取款机就像两个临界对象。

这只是我的见解。
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

14
 
学习了
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表