欢迎来到天天文库
浏览记录
ID:40750311
大小:41.50 KB
页数:5页
时间:2019-08-07
《Linux内核读写信号量 rwsem实现分析》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、读写信号量信号量根据用途不同,可以区分读和写两种操作方式。为提高信号量的效率引入rwsem,此锁使用的机会比较少,适用于读频繁的情况。头文件,类型structrw_semaphore,其必须在运行时进行显示的初始化:voidinit_rwsem(structrw_semaphore*sem);对于只读访问,使用如下PV:voiddown_read(structrw_semaphore*sem);intdown_read_trylock(structrw_semaphore*sem);//成功返回非零,其他返回零(特殊)voidup_read(
2、structrw_semaphore*sem);对于写入分别是:down_write,down_write_trylock,up_writerwsem允许一个写入者或无限个读者拥有该信号量。在2.6.21内核rwsem的实现中,所有读者和写者排队处理,处理完写者前面的所有读者后才处理到写者。在rwsem-spinlock.c中down_read实现如下:/**getareadlockonthesemaphore*/voidfastcall__sched__down_read(structrw_semaphore*sem){structrwsem_waiterwaiter;
3、structtask_struct*tsk;spin_lock_irq(&sem->wait_lock);//没有写者的情况下直接获取读者锁if(sem->activity>=0&&list_empty(&sem->wait_list)){/*granted*/sem->activity++;spin_unlock_irq(&sem->wait_lock);gotoout;}//否则有写者的情况下,加入到排队队列中tsk=current;set_task_state(tsk,TASK_UNINTERRUPTIBLE);//进程不可中断/*setupmyownstyleof
4、waitqueue*/waiter.task=tsk;waiter.flags=RWSEM_WAITING_FOR_READ;get_task_struct(tsk);list_add_tail(&waiter.list,&sem->wait_list);//加入到排队队列中/*wedon'tneedtotouchthesemaphorestructanymore*/spin_unlock_irq(&sem->wait_lock);/*waittobegiventhelock*/for(;;){//task有效的时候,继续调度,在up中会被设置成NULL,进而去调度if(
5、!waiter.task)break;schedule();set_task_state(tsk,TASK_UNINTERRUPTIBLE);}tsk->state=TASK_RUNNING;out:;}/**releaseareadlockonthesemaphore*/voidfastcall__up_read(structrw_semaphore*sem){unsignedlongflags;spin_lock_irqsave(&sem->wait_lock,flags);//释放读者锁的时候,若wait_list不为空的时候,证明等待队列中存在写者锁请求if(--
6、sem->activity==0&&!list_empty(&sem->wait_list))sem=__rwsem_wake_one_writer(sem);//此函数下面分析spin_unlock_irqrestore(&sem->wait_lock,flags);}down_write函数会直接调用以下函数/*getawritelockonthesemaphore*-weincrementthewaitingcountanywaytoindicateanexclusivelock*/voidfastcall__sched__down_write_nested(str
7、uctrw_semaphore*sem,intsubclass){structrwsem_waiterwaiter;structtask_struct*tsk;spin_lock_irq(&sem->wait_lock);//activity==0且队列中没有等待时,此时没有读者和写者,直接获取写者锁。if(sem->activity==0&&list_empty(&sem->wait_list)){/*granted*/sem->activity=-1;spin_unlock_irq(&sem->wait_lock);got
此文档下载收益归作者所有