自行实现锁

  在进行多线程编程的时候,需要对共享数据,或者说竞争数据进行上锁,通常我们都是使用操作系统提供的数据结构和接口,比如linux下的mutex结构。使用现成的锁结构能满足绝大多数的需求,不过针对一些特殊情况,可能需要自己实现锁,比如想检测程序中是否发生了死锁。

  本文主要针对TAS这种锁的方式进行讨论和实现。TAS简单的说就是test and set,针对一个多个线程共享的数据,进行测试和设置数值,见得说,有一个整数A,如果线程1设置A为1,那么线程2就认为是被锁上了。那么在intel X86平台上,我们可以使用XCHG(交换寄存器数值)来实现TAS。

  首先定义我们自己的mutex结构:

struct mutex {
    int value;
};

  然后我们定义我们的enter_mutex:

void enter_mutex(mutex* m) {
    int* flag = &m->value;
    __asm {
    enter_region:
        MOV eax, 1
        MOV ebx, flag
        XCHG eax, dword ptr [ebx] 
        CMP eax, 0
        JNE enter_region
    }
}

  再定义我们的leave_mutex:

void leave_mutex(mutex* m) {
    int* flag = &m->value;

    __asm {
        MOV eax, 0
        MOV ebx, flag
        XCHG dword ptr [ebx], eax
    }

    return;
}

  我们这里使用的IDE是vs2012,测试可用。

  PS:我们这里没有针对代码在多CPU情况下的乱序执行进行考虑,默认有memory barrier。

  XCHG方法实现锁的原理,就是将我们自己的mutex中的value在进行加锁的时候设置为1,如果这时候其他线程也请求这个锁,就会发现值为1,然后循环等待。在解锁的时候简单的将mutex中的value设置为0,然后退出,这样其他某个等待锁的线程,就可以获得锁了。

原文地址:https://www.cnblogs.com/chobits/p/4798508.html