打印

请教一下农民讲习所

[复制链接]
楼主: 一只小绵羊
手机看帖
扫描二维码
随时随地手机跟帖
61
到此为止,讨论已近严重偏离了楼主的提问,楼主的问题在3楼。而后面60多楼的讨论,基本都是围绕“定义mCount全局变量”是否有必要。使用mCount全局变量这个用法,应该不是21ic上的某个人原创的,恕我知识面不宽,只能举出两个例子:CVAVR的用户向导生成的串口代码(见47楼)和UCOSII的消息队列(见37楼)。
冷漠大侠在推导出了39楼的mCount = |pIn - pOut|公式的30小时之后,告诉我们它的公式可能需要在缓冲区大小是2的n次幂的情况下才凑效,而且pOut/pIn不再是指针,而是数组下标,是从0开始的数值。这才比较勉强地能够说明,mCount似乎并没有什么用,虽然他的那些条件跟楼主给出的例子已经完全不符。
而无论如何,我都不会觉得“冷漠”和其他认为“环形缓冲器不需要pQueueBuffer->mCount这么个成员”的人,比编译器的设计者和操作系统的作者更聪明。所以显然他们的观点不能说服我。我在前面也说了,对同一件事,不同的人又不同看法,这很正常。
至于道歉,呵呵,that's ridiculous. 说你是“歪理”,只是说你不正确,如果你非得觉得“歪理”有些贬义的话,那也是冲着你之前的冷嘲热讽来的。所以道歉是不可能了。
刚才仔细翻了一下所有回帖,发现这种争论真的没什么意义,还要浪费不少工作时间。来21ic,是为了获得帮助,给予帮助,是交流学习的目的,而不是看某些人的冷嘲热讽来的,这种无意义的争论不会使人有丝毫的进步,只会浪费时间。所以对于这个帖子,我不会再跟帖,说到做到。

使用特权

评论回复
62
原野之狼| | 2010-1-7 00:12 | 只看该作者
READ THE SOURCE CODE
AND THEN MAKE IT
THEN EXECUTE IT

冷漠大侠的伪码也让我有些头晕
desert_hawk兄的很多观点都是正确的 增加一个变量来存储计数 未必不可
而不用这个变量 互斥操作还是需要的 我在之前已经说过这个 所以多一个“多余”的变量可以接受

使用特权

评论回复
63
一只小绵羊|  楼主 | 2010-1-7 00:51 | 只看该作者
:P条条大路通罗马吧
明白了的关中断,但是不能直接关还是要用到ucos enter_critical()那种,都则重复调用的时候会出问题

使用特权

评论回复
64
冷漠| | 2010-1-7 09:43 | 只看该作者
本帖最后由 冷漠 于 2010-1-7 09:45 编辑

请教62楼版主,lxyppc 网友的代码使用了互斥吗?互斥是由于2个函数使用了同一共享资源mCount 而引发的竞争才使用的机制,是能避免就避免的。且不说mCount 这个变量有什么用,是不是在push( )和pop( )2个函数中都不可避免地要用到?即使是都要用到,那么“变量的赋值和引用越近越好,变量的跨度和生存时间越小越好。”这是使用变量的基本规则吧?

    我能够在本函数内部利用已知条件求得局部变量 mCount,我为什么要把自己的“攻击窗口”扩大到另一个函数?!
    只有在迫不得已的情况下才不得不存在攻击窗口。41楼认为无法利用已知条件求得mCount ,所以不得不设立了大跨度、长存活时间的攻击窗口。那么 lxyppc 怎么就能利用函数内部已知条件求得 mCount ?特别是Keil 也是这么做的。——能够缩小变量作用域,取决于程序员的“智力上的可管理性。”(而不是“方便性”)

    我是没有观点的人,我不会比 keil 或者 lxyppc 还高明。

   lxyppc 能想到环形缓冲器这一特点,绝对不是简单的人。( 所以我说所长自己还没整明白呢。不是因为我比谁高明,是因为我悟了一年才悟出lxyppc ,才看出所长的程序概念局限在哪。)

下面看 Keil 怎么写的:

使用特权

评论回复
65
zhouxin1980| | 2010-1-7 10:21 | 只看该作者
请教62楼版主,lxyppc 网友的代码使用了互斥吗?互斥是由于2个函数使用了同一共享资源mCount 而引发的竞争才使用的机制,是能避免就避免的。且不说mCount 这个变量有什么用,是不是在push( )和pop( )2个函数中都不可 ...
冷漠 发表于 2010-1-7 09:43


此言谬矣。
size_t GetRingCount()
{
  size_t size = (Ring.pIn - Ring.pOut) % RING_SIZE;
  if( (size == 0) && (Ring.pIn != Ring.pOut) ){
    size = RING_SIZE;
  }
  return  size;
}
Ring.pOut也是要互斥保护的,除非是32位的ARM。农民的mCount是8位变量,根本不需要互斥保护,冷漠还需要学习很多。

使用特权

评论回复
66
冷漠| | 2010-1-7 10:37 | 只看该作者

请教楼上,lxyppc 的 size_t 是什么类型?8/16/32位?

本帖最后由 冷漠 于 2010-1-7 10:57 编辑

有道理,65楼没做过的人比做过的人还考虑的周全。比Keil 还厉害。咱学了半天Keil 的写法,楞没发现这些老外没加互斥!

若是C51,size、 Ring.pIn、Ring.pOut  应该设为uchar类型。

可是,lxyppc  没指定多少位的单片机,他的 size_t 没说是8位/16/32位。也许他的程序适用于他的16位单片机甚或PC机?他是C程序,可以移植的。教人一个概念。

哈哈,发现 lxyppc没加 #include <REG51.H> ,“他没用互斥,跟我差远了,Keil / lxyppc 要学习的东西还很多。”

65楼,还是咱们中国人厉害。

使用特权

评论回复
67
zhouxin1980| | 2010-1-7 10:42 | 只看该作者
到此为止,讨论已近严重偏离了楼主的提问,楼主的问题在3楼。而后面60多楼的讨论,基本都是围绕“定义mCount全局变量”是否有必要。使用mCount全局变量这个用法,应该不是21ic上的某个人原创的,恕我知识面不宽,只 ...
desert_hawk 发表于 2010-1-6 23:10


desert_hawk要耐心,只要讨论清楚,冷漠还是会接受意见的。

使用特权

评论回复
68
arm_fan168| | 2010-1-7 10:43 | 只看该作者
楼主在二楼的变量flagCAN1RecData--;也是8位啊,由LDRB     r0,[r0,#0]  ;指令能看出来是8位。同样需要互斥。需不需要互斥,跟指令功能有关系。

使用特权

评论回复
69
冷漠| | 2010-1-7 11:06 | 只看该作者
HWM 老师是给学生讲C语言课程的。看不懂他在说什么?

互个鬼斥保护。

收发各建一环队,各队的插入和提取在其头尾操作。要碰头,不是空了就是满了,只要有空满标志即可,不会打架地。


哪位觉得自己比HWM老师还高明,请他来讲课。什么叫攻击窗口?什么叫mCout的跨度和生存时间?为什么要尽量缩小变量作用域?

使用特权

评论回复
70
lxyppc| | 2010-1-7 11:18 | 只看该作者
此言谬矣。
size_t GetRingCount()
{
  size_t size = (Ring.pIn - Ring.pOut) % RING_SIZE;
  if( (size == 0) && (Ring.pIn != Ring.pOut) ){
    size = RING_SIZE;
  }
  return  size;
}
Ring.pOut也是要互斥 ...
zhouxin1980 发表于 2010-1-7 10:21


要改的话,可以改成这样的。不过在项目中好像很少会用到这个函数
size_t GetRingCount()
{
  size_t size = Ring.pIn - Ring.pOut;
  if( ((size%RING_SIZE) == 0) && (size) ){
    size = RING_SIZE;
  }
  return  size;
}

使用特权

评论回复
71
lxyppc| | 2010-1-7 11:28 | 只看该作者
本帖最后由 lxyppc 于 2010-1-7 11:30 编辑

环形缓冲可以当作是一个圆
pIn与pOut的差看作是夹角  对于角度有 theta = theta + N*2*PI
用夹角来表示距离的话就有
这里的2*PI可以看作是RING_SIZE
pIn - pOut = dist = dist + N*RING_SIZE;
同样 theta = theta % (2*PI)
       dist = dist % RING_SIZE
       当RING_SIZE与 (1<<(sizeof(size_t)*8))相等时
     dist%RING_SIZE 相当于 (size_t)dist
当pIn与pOut为指针时,指针相减表示取两指针的距离即dist,所以pIn与pOut换成指针也没有什么区别

使用特权

评论回复
72
冷漠| | 2010-1-7 14:37 | 只看该作者
还有谁什么地方不懂,71楼的程序所包含的概念内容足以写一遍论文了。

先讲一个概念内容:

使用特权

评论回复
73
冷漠| | 2010-1-7 14:38 | 只看该作者
本帖最后由 冷漠 于 2010-1-7 14:55 编辑
65楼 :
此言谬矣。
size_t GetRingCount()
{
  size_t size = (Ring.pIn - Ring.pOut) % RING_SIZE;
  if( (size == 0) && (Ring.pIn != Ring.pOut) ){
    size = RING_SIZE;
  }
  return  size;
}
Ring.pOut也是要互斥保护的,除非是32位的ARM。农民的mCount是8位变量,根本不需要互斥保护,冷漠还需要学习很多。



一般来说,我一介菜鸟能够仰视发现高手“不懂装懂”的形态,是一件感觉非常好玩、得意的事情:

“Ring.pOut也是要互斥保护的,...”???!!!
Ring.pOut 对前台中断调用函数PushRing ( ) 来说,是只读数据,只有后台函数PopRing ( )才能修改写入这个变量(资源),它是共享资源却不是临界资源。用HWM老师的话来说:“互个鬼斥!”

size=Ring.pIn - Ring.pOut;

即使 Ring.pIn 和 Ring.pOut 是在8位处理器上的 uint 双字节变量,但是2者都不是临界资源:

1、PushRing ( )只能对 Ring.pIn 进行修改写入,对 PushRing ( )来说,Ring.pOut 是只读数据;
2、PopRing ( )只能对 Ring.pOut 进行修改写入,对 PopRing (  )来说,Ring.pIn  是只读数据;

哪里有临界资源?没有临界资源,谈什么互斥?—— 看上去65楼比谁都懂。

这正是 lxyppc 的程序精彩的地方,让65楼一看,成了缺陷? 这就是人和人之间的差别。   别人若没这点本事,敢拿个完整的程序来混 300元?

要是我不说,65楼看的出来吗?我若说错了,是我不懂装懂。麻烦请继续指正。

抄一段教材上写的:摘自《Windows 操作系统原理》第2版  P110

“多个进程在对临界资源进行访问,特别是进行写入或修改操作时,必须互斥地进行。计算机系统中也有一些可以同时访问的共享资源不是临界资源,如只读数据。”

看来我还需要更多地学习,看来HWM,lxyppc , Keil 他们都错了。

使用特权

评论回复
74
原野之狼| | 2010-1-7 15:23 | 只看该作者
“多个进程在对临界资源进行访问,特别是进行写入或修改操作时,必须互斥地进行。计算机系统中也有一些可以同时访问的共享资源不是临界资源,如只读数据。”

但是在这里 pin 和 pout都不是只读数据。

使用特权

评论回复
75
一只小绵羊|  楼主 | 2010-1-7 15:38 | 只看该作者
73楼的这个我记得“救火车”曾经有个51上的例子,就是因为一个16bit的变量,当从0x00ff加1的时候,中间被打断,造成在主函数中读到的数据为0x1ff, 这种情况就会出错了,虽然它在调用的函数中是只读的。
就像在主函数中调用pIn - pOut = dist ,如果中间被打断pIn出现上述问题也会出错。

使用特权

评论回复
76
一只小绵羊|  楼主 | 2010-1-7 16:12 | 只看该作者
还有谁什么地方不懂,71楼的程序所包含的概念内容足以写一遍论文了。

先讲一个概念内容:
冷漠 发表于 2010-1-7 14:37


有点不明白呀,pin和pout是变量的时候,计算数量直接减法可以,当他们是指针的时候也可以吗??
你给贴个代码讲讲。

使用特权

评论回复
77
sz_kd| | 2010-1-7 16:22 | 只看该作者
unsigned char 时候直接减也应该一样吧,都是表示位置偏移

使用特权

评论回复
78
zhouxin1980| | 2010-1-7 16:25 | 只看该作者
到此为止,讨论已近严重偏离了楼主的提问,楼主的问题在3楼。而后面60多楼的讨论,基本都是围绕“定义mCount全局变量”是否有必要。使用mCount全局变量这个用法,应该不是21ic上的某个人原创的,恕我知识面不宽,只 ...
desert_hawk 发表于 2010-1-6 23:10


desert_hawk,你是对的,我错了。67楼当我没说,我闭嘴。

使用特权

评论回复
79
冷漠| | 2010-1-7 16:30 | 只看该作者
本帖最后由 冷漠 于 2010-1-7 17:12 编辑

74楼版主能否给我讲讲,PushRing( )函数是如何修改pOut的?HWM说过了,不搭界的2个指针, lxyppc 用的是uint。

1、PushRing ( )只能对 Ring.pIn 进行修改写入,Ring.pOut 对 PushRing ( )来说, 是只读数据(变量);

一头雾水,难道您说的是 pOut  8位机双字节的问题?那就16位机好了。或者那就uchar好了。

还真不知道mCount有什么用?是Push ( )要用还是Pop ( ) ,如果不是2者都要用,就无所谓临界资源,如果仅仅Push ( )用,谈互斥?

莫须有的东西,也拿来争论?

        并没看到KEIL程序用到这个变量,难道是咱们中国人考虑问题更全面?看上去都挺懂的,互斥啦,队列啦,一个比一个厉害,就是不知道互斥保护的资源是个啥。



使用特权

评论回复
80
一只小绵羊|  楼主 | 2010-1-7 16:33 | 只看该作者
本帖最后由 一只小绵羊 于 2010-1-7 16:35 编辑

难道您说的是 pOut  8位机双字节的问题?

恩,我就是说的这个,知道就行了。74楼大概也是这个意思吧。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则