我被要求用c实现一个使用比较和交换的无锁队列,然而我对指针的知识相当有限。
我一直在使用下面的代码来测试我的出队实现(尚未完成),但我认为它是无限循环的,因为我不太确定如何正确使用指针/操作符的地址。
我被赋予了这个CAS函数来使用,因为我对汇编器一无所知。
long __cdecl compare_exchange(long *flag, long oldvalue, long newvalue)
{
__asm
{
mov ecx, flag
mov eax, oldvalue
mov ebx, newvalue
lock cmpxchg [ecx], ebx
jz iftrue
}
return 0;
iftrue: return 1;
}我当前的(相关)代码如下所示...
typedef struct QueueItem
{
int data;
struct QueueItem* next;
}item;
struct Queue
{
item *head;
item *tail;
}*queue;
int Dequeue()
{
item *head;
do
{
head = queue->head;
if(head == NULL)
return NULL_ITEM;
printf("%d, %d, %d\n", (long *)queue->head, (long)&head, (long)&head->next);
}
while(!compare_exchange((long *)queue->head, (long)&head, (long)&head->next)); // Infinite loop.
return head->data;
}
int main(int argc, char *argv[])
{
item i, j;
queue = (struct Queue *) malloc(sizeof(struct Queue));
// Manually enqueue some data for testing dequeue.
i.data = 5;
j.data = 10;
i.next = &j;
j.next = NULL;
queue->head = &i;
printf("Dequeued: %d\n", Dequeue());
printf("Dequeued: %d\n", Dequeue());
}我应该在do while循环中使用not操作符吗?如果我不使用这个操作符,我会得到一个"Dequeued 5“x2的输出,这表明交换没有发生,我应该使用not。如果是这样的话,我错在哪里?我敢打赌这是一个指针/地址运算符问题。
发布于 2012-08-24 11:51:02
在指针和值上有混淆。以下是更正后的代码:
do
{
head = queue->head;
if(head == NULL)
return 0;
printf("%d, %d, %d %d\n", (long *)queue->head, (long)head, (long)head->next, head->data);
} while (!compare_exchange((long *)&queue->head, (long)head, (long)head->next));您试图写入queue->head指向的内容,而不是queue->head本身的值。
此外,为了让它在多核上正常工作,我认为您需要将头部定义为易失性。
struct Queue
{
volatile item *head;
item *tail;
}*queue;https://stackoverflow.com/questions/12102595
复制相似问题