Chinaunix首页 | 论坛 | 博客
  • 博客访问: 493853
  • 博文数量: 223
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2145
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-01 10:23
个人简介

该坚持的时候坚持,该妥协的时候妥协,该放弃的时候放弃

文章分类

全部博文(223)

文章存档

2017年(56)

2016年(118)

2015年(3)

2014年(46)

我的朋友

分类: LINUX

2014-12-24 21:53:15

可睡眠锁 Mutex(互斥量)

一次只能被一个对象所持有

类似用户空间的glibc中的pthread_mutex_lock

持有mutex后任然可以睡眠(可以被调度出去)

使用

#include

初始化:

编译时初始化:DEFINE_MUTE()

运行时初始化:mutex_init()

持有锁:

mutex_lock()/mutex_lock_interruptible()/mutex_lock_killable()

mutex_lock_killable()只会响应SIGKILL信号

释放锁

mutex_unlock()
使用例子:

  1. #include
  2. static DEFINE_MUTEX(my_lock);

  3. static void writer_do(void)
  4. {
  5.     mutex_lock(&my_lock);
  6.     pmy_data->count1 ++;
  7.     pmy_data->count2 += 10;
  8.     mutex_unlock(&my_lock);
  9. }

Semaphore(信号量)

Linux中的信号量是一种睡眠锁,如果有一个任务师徒获得一个不可用的信号量时,信号量会将其推进一个等待队列,然后让其睡眠。这时处理器能重获自由,从而去执行其它代码。当持有的信号量可用后,处于等待队列中的那个任务将被唤醒,并获得该信号量。

持有锁时:如果当前值为0,则睡眠,等值信号量的值变为非0。否则,则信号值的值减1

释放锁时:将信号量的值加1,如果有进程在等待该信号量则将其唤醒。

使用:

#include

初始化:

编译时初始化DEFINE_SEMAPHORE(sem,val)

运行时初始化    sema_init(sem, val)

持有锁

down()/down_interruptible()/down_killable()

-down_killable()只会响应SIGKILL

释放锁

up()
使用示例:

  1. #include
  2. static DEFINE_SEMAPHORE(mylock);

  3. static void writer_do(void)
  4. {
  5.     down(&mylock);
  6.     pmy_data->count1 ++;
  7.     pmy_data->count2 += 10;
  8.     up(&mylock);
  9. }


Rwsem(读写信号量)

    与自旋锁一样,信号量也有区分读-写访问的可能,与读-写自旋锁和普通自旋锁之间的关系差不多,读-写信号量也要比普通信号量更具优势。


使用:

#include

初始化:

编译时初始化 DECLARE_RWSEM()

运行时初始化 init_rwsem()

读者:

持有锁 down_read()

释放锁 up_read()

写着:

持有锁 down_write()

释放锁 up_write()
使用示例:

  1. #include

  2. static DECLARE_RWSEM(myrwlock);

  3. static void reader_do(void)
  4. {
  5.     down_read(&myrwlock);
  6.     printk("read count1 %d count2 %d\n", pmy_data->count1, pmy_data->count2);
  7.     up_read(&myrwlock);
  8. }

  9. static void writer_do(void)
  10. {
  11.     down_write(&myrwlock);
  12.     pmy_data->count1 ++;
  13.     pmy_data->count2 += 10;
  14.     up_write(&myrwlock);
  15. }


completion

    如果在内核中一个任务需要发出信号通知另一个任务发生了某个特定时间,利用完成变量(completion variable)是使两个任务得以同步的简单方法。果一个任务要执行一些工作时,另一个任务就会在完成变量上等待的确如此——思想是一样的。事实上,完成变量仅仅提供了代替信号量的一个简单的解决方法。

初始化

编译时初始化 DECLARE_COMPLETION()

运行时初始化 init_completion()

等待事件

wait_for_completion()/wait_for_completion_interruptible()/wait_for_completion_killable()/wait_for_completion_io()/wait_for_completion_xxx_timeout

事情完成

Complete()/complete_all()

complete()只会唤醒一个正在等待的进程而complete_all()则唤醒
使用示例:

  1. #include

  2. static DECLARE_RWSEM(myrwlock);
  3. static DECLARE_COMPLETION(mycomp);

  4. static void reader_do(void)
  5. {
  6.     wait_for_completion(&mycomp);
  7.     down_read(&myrwlock);
  8.     printk("read count1 %d count2 %d\n", pmy_data->count1, pmy_data->count2);
  9.     up_read(&myrwlock);
  10. }

  11. static void writer_do(void)
  12. {
  13.     down_write(&myrwlock);
  14.     pmy_data->count1 ++;
  15.     pmy_data->count2 += 10;
  16.     up_write(&myrwlock);
  17.     complete_all(&mycomp);
  18. }


针对dmesg查看时输出信息太多,可以在/var/log/messages中查看。

dmesg

echo > /var/log/messages

insmod exam.ko

rmmod exam

vi /var/log/messages



阅读(1636) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~