C 互斥实现中的死锁和竞争条件

C 互斥实现中的死锁和竞争条件,c,concurrency,mutex,deadlock,race-condition,C,Concurrency,Mutex,Deadlock,Race Condition,我试图在C中使用原子汇编指令“bts”实现互斥,以原子方式设置位并返回原始值。 但是,当我运行以下代码时,它偶尔会死锁,并经常显示竞争条件: #include <stdio.h> #include <stdlib.h> #include <pthread.h> typedef unsigned char mutex; #define MUTEX_FREE 0 #define MUTEX_BUSY 1 // adapted from http://www.a

我试图在C中使用原子汇编指令“bts”实现互斥,以原子方式设置位并返回原始值。 但是,当我运行以下代码时,它偶尔会死锁,并经常显示竞争条件:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

typedef unsigned char mutex;
#define MUTEX_FREE 0
#define MUTEX_BUSY 1

// adapted from http://www.acm.uiuc.edu/sigops/roll_your_own/i386/atomic.html
mutex testAndSet(mutex *m) {
    int result;
    asm ("bts $0, %1; sbbl %0, %0"
         :"=r" (result)
         :"m" (*m)
         :"memory");
    return (result & 1);
}

void P(mutex *m) {
    // Must use atomic testAndSet to avoid race conditions
    while(testAndSet(m) == MUTEX_BUSY)
        usleep(10);
}

void V(mutex *m) {
    *m = MUTEX_FREE;
}

//////////////
// Test:
//////////////

const int NTHREADS = 100;
const int NINCS = 100;

int counter = 0;
mutex m = MUTEX_FREE;

void criticalSection() {
    int i;
    for(i=0;i<NINCS;i++) {
        P(&m);
        counter++;
        V(&m);
    }
}

int main() {
    int i;
    pthread_t threads[NTHREADS];
    for(i=0; i<NTHREADS; i++) {
        pthread_create(&threads[i], NULL, (void *) &criticalSection, NULL);
    }
    for(i=0; i<NTHREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    printf("got counter=%d, expected=%d\n", counter, NTHREADS*NINCS);
}
原始代码中的竞争条件在哪里?“bts”指令是否应该是原子的,以保证线程安全

此外,我修改后的解决方案是否正确

(我正在运行OS X 10.8并使用gcc编译。)

尝试使用锁定内存总线:

asm ("lock bts $0, %1; ...");
xchg
指令之所以有效,是因为无论是否存在
LOCK
前缀,它总是断言
LOCK
信号。

尝试使用锁定内存总线:

asm ("lock bts $0, %1; ...");

xchg
指令之所以有效,是因为无论是否存在
LOCK
前缀,该指令总是断言
LOCK#
信号。

您在哪里读到的
bts
是原子的?(我不太熟悉x86汇编,但我不记得读过那篇文章。)添加x86和汇编标记,这样您就可以获得更多帮助这里是我读到的
bts
是原子的(至少对于i386):您在哪里读到的
bts
是原子的?(我不太熟悉x86汇编,但我不记得读过这篇文章。)添加x86和汇编标记,这样您就可以获得更多帮助这里是我读到的
bts
是原子的(至少对于i386):