免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2183 | 回复: 5
打印 上一主题 下一主题

[内核同步] 请教驱动程序中信号量/自旋锁的使用问题。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-06-07 11:37 |只看该作者 |倒序浏览
各位大侠:
    在编写字符设备驱动过程中,需要考虑多个线程同时访问该字符设备的问题,需要互斥保护,同一时刻只允许一个线程对字符设备进行读写。但不知道用信号量还是自旋锁更好(自己理解感觉自旋锁似乎不适合用在这里),请各位大侠指点。
    我的驱动中write方法函数结构如下:
    write(..., ..., ...)
      {
          copy_from_usr();//将用户空间的数据传递到内核空间
      
       check_state();//查询设备状态是否可写,如果可写继续执行,不可写则等待一段时间后write返回

       dma_transfer();//发起DMA传输
       wait_dma_transfer_complete();//等待DMA传输结束,DMA传输结束条件在我编写的另一个DMA中断处理函数中赋值,500ms未触发DMA传输结束中断则超时返回

       after_process();//后续处理,根据DMA中断处理函数中的设置的结果,判断本次写操作是否成功,返回相应的值
      }


    read方法函数结构如下:
   read(..., ..., ...)
    {
        read_from_circle_buf();//从内核空间一个循环缓冲区中读取数据,该循环缓冲区的数据在我编写的另一个中断处理函数中写入,该中断处理函数处理字符设备发来的数据

      copy_to_usr();//将数据传递到用户空间
    }

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
2 [报告]
发表于 2013-06-07 13:26 |只看该作者
回复 1# xidianunix
如果对实时性要去不是太高的话,建议用信号量。自旋锁不太适合这种长时间等待的环境。

   

论坛徽章:
0
3 [报告]
发表于 2013-06-07 13:43 来自手机 |只看该作者
那么在进入read/write函数后,首先获取信号量,函数返回前释放信号量,应该是没问题的吧?即使中间有等待dma传输结束中断也没问题吧?

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
4 [报告]
发表于 2013-06-07 17:19 |只看该作者
回复 3# xidianunix
自旋锁
        spinlock_t数据类型,spin_lock(&lock)和spin_unlock(&lock)是加锁和解锁
        等待解锁的进程将反复检查锁是否释放,而不会进入睡眠状态(忙等待),所以常用于短期保护某段代码
        同时,持有自旋锁的进程也不允许睡眠,不然会造成死锁——因为睡眠可能造成持有锁的进程被重新调度,而再次申请自己已持有的锁
        如果是单核处理器,则自旋锁定义为空操作,因为简单的关闭中断即可实现互斥
互斥量
        struct mutex数据类型,mutex_lock(struct mutex *lock)和mutex_unlock(struct mutex *lock)是加锁和解锁
        竞争互斥量时需要进行进程睡眠和唤醒,代价较高,所以不适于短期代码保护,适用于保护较长的临界区


互斥量不能用于中断环境中。互斥量操作期间,运行被中断打断。所有你的场景应该是合适用互斥量的。
   

论坛徽章:
0
5 [报告]
发表于 2013-06-09 10:26 |只看该作者
回复 4# 瀚海书香

谢谢瀚海书香的回复。
我在驱动程序中加入了信号量进行保护,用来保证对设备读/写操作的互斥,读操作和写操作可同时进行,不能同时读或者同时写,如下:
1、声明2个信号量:static int DECLARE_MUTEX(write_sem);     static int DECLARE_MUTEX(read_sem);
2、在进入write或read函数后,获取信号量:down(&xxx_sem);
3、在write或read函数返回前,释放信号量:up(&xxx_sem);

麻烦您再看看是否OK?以前没写过内核互斥的代码,非常感谢!

   

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
6 [报告]
发表于 2013-06-09 12:18 |只看该作者
回复 5# xidianunix
谢谢瀚海书香的回复。
我在驱动程序中加入了信号量进行保护,用来保证对设备读/写操作的互斥,读操作和写操作可同时进行,不能同时读或者同时写,如下:
1、声明2个信号量:static int DECLARE_MUTEX(write_sem);     static int DECLARE_MUTEX(read_sem);
2、在进入write或read函数后,获取信号量:down(&xxx_sem);
3、在write或read函数返回前,释放信号量:up(&xxx_sem);

麻烦您再看看是否OK?以前没写过内核互斥的代码,非常感谢!


这样写是可以的。不过一般的驱动程序都是可以被信号打断的,这也是很多应用程序调用系统调用read/write都会处理EINTR错误。所以最好这样写:

if (down_interruptible(&xxx_sem)) {
        return -ERESTARTSYS;
}

........



up(&xxx_sem);
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP