Atomic_t
Atomic_t atom = ATOMIC_INIT(1);
Atomic_dec_and_test(&atom);
Atomic_inc(&atom);
Spin_lock_t
Spinlock_t lock;
Spin_lock_init(&lock);
-DEFINE_SPINLOCK(lock);
Spin_lock(&lock);
Spin_trylock(&lock);
Spin_unlock(&lock);
Rwlock_t
Rwlock_t lock;
Rwlock_init(&lock);
-DEFINE_RWLOCK(lock);
Read_lock(&lock);
Read_trylock(&lock);
Read_unlock(&lock);
Write_lock(&lock);
Write_trylock(&lock);
Write_unlock(&lock);
不能同时申请读自旋锁和写自旋锁,否则照成死锁:
-read_lock(&lock);
-write_lock(&lock);//执行就造成死锁
获取写锁时,计数器减0x01000000,判断是否为0,是则表示没有其他的读者或者写者,获取锁成功;不为0则表示有其他读者或者写者,获取锁失败。
seqlock_t
顺序锁与读写自旋锁类似,只是为写锁赋予了更高的权限。在读写自旋锁rwlock_t中,当读锁获取读自旋锁时,写锁必须等待。顺序锁在获取读锁的时候,仍然可以获取写锁,并立即执行写临界区的代码。写锁永远不会被读锁阻塞。写锁仍然可以被写锁阻塞。
Typedef struct {
unsigned sequence;
spinlock_t lock;
}seqlock_t;
当获取顺序锁write_seqlock函数时,seqlock_t.sequence变量会被加1.释放写顺序锁write_sequnlock函数时,该变量仍然加1.因此,在获取顺序锁,但没有释放的时候,seqlock_t.sequence变量的值是奇数。释放写顺序锁后,该变量是偶数。
//标准执行读临界区代码:
Unsigned seq;
Do{
seq = read_seqbegin(&seqlock);
//读取共享区代码。
}while(read_seqretry(&seqlock, seq));
由上段代码可以看出,在执行读临界区代码的时候,如果发生写操作,read_seqretry函数会返回非0值。代码将do...while再执行一次。也就是说临界区代码发生了变化,需要重新读取一次。
//标准执行写临界区代码
Seqlock_t lock;
Seqlock_init(&lock);
Write_seqlock(&lock);
//写临界区代码。
Write_sequnlock(&lock);
semaphore
在未获取信号量的时候,进入休眠状态。
信号量利用等待队列实现对临界区的锁定。
semaphore sem;
Sema_init(&sem, 1);//后面的数字表示信号量的初始值
Down(&sem); //P操作,申请信号量。
Up(&sem); //V操作,释放信号量。
down函数用于获取信号量,没有获取到信号量导致进程休眠,中断无法唤醒,不能再中断上下文中使用。
Down_interrupt(&sem);//在休眠中可以被中断唤醒.
Down_trylock(&sem);//不会休眠,可用于中断上下文。
Rw_semaphore
多个读,单个写
rw_semaphore rw_sem;
Init_rwsem(&rw_sem);
Down_read(&rw_sem);
… …//临界代码段
Up_read(&rw_sem);
Down_write(&rw_sem);
… …//写临界代码段
Up_write(&rw_sem);
mutex
Struct mutex my_mutex;
Mutex_lock(&my_mutex);
Mutex_unlock(&my_mutex);
Mutex_trylock(&my_mutex);
Mutex_interruptible(&my_mutex);
completion完成量 完成量用于一个执行单元等待另一个执行单元执行完成某项工作。 Struct completion{ unsigned int done;//标识任务已经完成的次数。 wait_queue_head_t wait; }; Struct completion my_completion; Init_completion(&my_completion); -DECLARE_COMPLETION(my_completion); //使completion.done的值减1 Wait_for_completion(&my_completion);//不能被中断打断 //可以被中断打断 Wait_for_completion_interruptible(&my_completion); Complete(&my_completion); Complete_all(&my_completion); complete使completion.done的值加1,complete_all使该值设为int的最大值。