您的位置:首页 > 运维架构 > Linux

linux 并发控制总结

2014-02-04 22:44 267 查看
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的最大值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: