我遇到了一个有趣的问题,我希望这完全是我的错。
我有从队列中读取的代码,如:
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-&gt; index是一个坏值,但是当printf显示它时显示一个完全有效的值!例如:
RX EVENT BAD NDX: ndx=1 h=64
if语句清楚地表明条件必须是&lt; = 0 OR&gt; 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。
答案 0 :(得分:2)
我的猜测是,在编写evt_tail
字段之前,向尾部添加事件的函数将更改index
。这允许您的读者访问仍在编写过程中的事件。