4

我遇到了一个有趣的问题,我希望这完全是我的错。

我有从队列中读取的代码,如:

 do {
    evt       = &newevts[ evt_head++ ];
    evt_head &=  MAX_EVENTS;

    if (evt->index <= 0 || evt->index > MAX_INDEX) {
         printf("RX EVENT BAD NDX: ndx=%d h=%d\n",evt->index, evt_head);
         continue;
    }

    //... etc ...

 } while(evt_head != evt_tail) ;

奇怪的问题是 if 语句可以评估为 evt->index 是一个坏值,但是当 printf 显示它显示一个完全有效的值!例子:

RX EVENT BAD NDX: ndx=1 h=64

if 语句清楚地表明条件必须是 <= 0 OR > 1024(最大索引)。更糟糕的是,这种情况只会偶尔发生一次。我正在使用 GCC,Centos 6.3。除此线程外,没有线程接触 evt_head。(我已经将它重命名了几次并重新编译以确保它。)

尾部由一个函数处理,该函数以与头部删除它们相同的方式将项目添加到队列中(递增然后 AND)。我还在事件结构本身内添加了一个计数器来记录头/尾值,因为事件被放入队列中,并且没有发现丢失或跳过的值。从字面上看,我好像读到了一些糟糕的记忆。但这太荒谬了——如果是这样的话,我希望系统崩溃或至少程序崩溃。

关于这在世界上如何偶尔发生的任何想法?(频率约为 100 次读取中的 1 次)我感谢任何输入!

typedef struct {
    int    index;
    int    event;
} EVENT;

#define  MAX_EVENTS  0x01ff
#define  MAX_INDEX   1024

没有线程或其他代码触及 evt_head。只有这个循环。队列永远不会接近满员。我也碰巧在进入添加到队列的例程时有一个“SPIN LOCK”(以准备稍后被其他线程访问),并在退出时有一个 UNLOCK。

4

1 回答 1

2

我的猜测是,将事件添加到尾部的函数会evt_tail在写入index字段之前发生变化。这允许您的读者访问仍在编写过程中的事件。

于 2013-01-22T06:09:45.990 回答