标签:
在进行多线程编程的时候,需要对共享数据,或者说竞争数据进行上锁,通常我们都是使用操作系统提供的数据结构和接口,比如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,然后退出,这样其他某个等待锁的线程,就可以获得锁了。
标签:
原文地址:http://www.cnblogs.com/chobits/p/4798508.html