Background:
工作中需要避免两个人同时在一台Linux部署测试环境,需要锁同步。(当然还有其他方法去避免这样的问题,比如用不同的权限设置)。Linux 里面真是强大,已经提供对文件加锁的工具。一类是flock,另外还有一组(lockfile-create, lockfile-check, lockfile-touch, lockfile-remove)。
Question:
但是计算机里面锁是如何实现的?需要借助原子操作。那原子操作如何实现呢?
如果是单CPU,可以用屏蔽中断,不去调度任何其他进程线程,保证指令的原子性。那么多CPU 又是如何保证的呢? 需要机器硬件支持。CUP提供的有原子指令,比如 Test-set,test-clear, 比如原子操作是通过DDR内部支持的,From wiki: http://en.wikipedia.org/wiki/Test-and-set
When CPU 1 issues a test-and-set instruction, the DPRAM first makes an "internal note" of this by storing the address of the memory location in a special place. If at this point, CPU 2 happens to issue a test-and-set instruction for the same memory location, the DPRAM first checks its "internal note", recognizes the situation, and issues a BUSY interrupt, which tells CPU 2 that it must wait and retry. This is an implementation of a busy waiting or spinlock using the interrupt mechanism. Since this all happens at hardware speeds, CPU 2's wait to get out of the spin-lock is very short.
Whether or not CPU 2 was trying access the memory location, the DPRAM performs the test given by CPU 1. If the test succeeds, the DPRAM sets the memory location to the value given by CPU 1. Then the DPRAM wipes out its "internal note" that CPU 1 was writing there. At this point, CPU 2 could issue a test-and-set, which would succeed.
”
当第一个CPU发出test-and-set 指令时,DPRAM 会给被访问的内存做一个标记。当其他CPU也访问该内存时,会检查其标志位。如果发现已经被设置标记位,则BUSY 中断返回告诉其已经被其他人访问,应该等待。 如果CPU 发现测试通过,将设置该内存为1,并清楚标记位。这时第二个CPU可以访问。
锁需要原子操作支持,原子操作需要硬件支持。可以锁是整个系统的全局资源,是属于内核部分。 这也可以解释,为什么多个CPU同时去获取一个锁,但是只有一个人获取到,其他的都没有。同样Semaphore 也同样可以用test-set 指令来实现,只是set变成加1,或者减1.
多线程编程里面少不了mutex, condition and semaphore. (http://www.cnblogs.com/zhyg6516/admin/EditPosts.aspx?opt=1)
Other Reference:
1. http://embedlinux.ycool.com/post.2944092.html【如何更好理解锁的范围,锁的有效性】
2. http://fxr.watson.org/fxr/source/arch/alpha/include/asm/system.h?v=linux-2.6#L359 [可以查看不同开源的操作系统的源码,可以查看lock在linux系统如何实现的]