他山之石,可以攻玉。
分类: LINUX
2012-07-18 00:18:23
1.定义初始化自旋锁
使用下面的语句就可以先定一个自旋锁变量,再对其进行初始化:
1 | spinlock_t lock; |
2 | spin_lock_init(&lock); |
也可以这样初始化一个自旋锁:
1 | spinlock_t lock=SPIN_LOCK_UNLOCKED; |
2.获得自旋锁
1 | void spin_lock(spinlock_t*); |
2 | int spin_trylock(spinlock_t*); |
使用spin_lock(&lock)这样的语句来获得自旋锁。如果一个线程可以获得自旋锁,它将马上返回;否则,它将自旋至自旋锁的保持者释放锁。
另外可以使用spin_trylock(&lock)来试图获得自旋锁。如果一个线程可以立即获得自旋锁,则返回真;否则,返回假,此时它并不自旋。
3.释放自旋锁
1 | void spin_unlock(spinlock_t*); |
使用spin_unlock(&lock)来释放一个已持有的自旋锁。注意这个函数必须和spin_lock或spin_trylock函数配套使用。
说明:
1、保护临界区的数据而不是临界区的代码。
2、在使用自旋锁时候,必须关闭本地中断,否则可能出现双重请求的死锁。
3、自旋锁是忙等锁,所以保护区域应尽可能短。
4、自旋锁不能递归使用。
二、信号量的使用
1,包含 include
数据结构如下:
struct semaphore { |
spinlock_t lock; |
| unsigned int count; |
struct list_head wait_list; |
}; |
count:初始化信号量时所设置的信号量值。
wait_list:等待队列,该队列中即为等待信号量的进程。
lock:自旋锁变量
1.定义初始化信号量
使用下面的代码可以定义并初始化信号量sem:
struct semaphore sem;
sem_init(&sem,val);
其中val即为信号量的初始值。
如果我们想使用互斥信号量,则使用下面的函数:
init_MUTEX(&sem);
这个函数会将sem的值初始为1,即等同于sem_init(&sem,1);
如果想将互斥信号量的初值设为0,则可以直接使用下面的函数:
init_MUTEX_LOCKED(&sem);
除上面的方法,可以使用下面的两个宏定义并初始化信号量:
DECLARE_MUTEX(name);
DECLARE_MUTEX_LOCKED(name);
其中name为变量名。
2.获得信号量
down(&sem);
进程使用该函数时,如果信号量值此时为0,则该进车会进入睡眠状态,因此该函数不能用于中断上下文中。
down_interruptibale(&sem);
该函数与down函数功能类似,只不过使用down而睡眠的进程不能被信号所打断,而使用down_interruptibale的函数则可以被信号打断。
如果想要在中断上下文使用信号量,则可以使用下面的函数:
dwon_try(&sem);
使用该函数时,如果进程可以获得信号量,则返回0;否则返回非0值,不会导致睡眠。
3.释放信号量
up(&sem);
该函数会释放信号量,如果此时等待队列中有进程,则唤醒一个。
转:主要摘自http://edsionte.com/techblog/archives/1820