互斥和同步

本文介绍了Linux系统中实现进程间互斥与同步的方法,包括信号量、自旋锁及原子操作等关键技术,并探讨了它们的应用场景与注意事项。
为什么要用到互斥,是由于cpu调度引起来的,任何一个进程或线程随时都有可能被终止, 运行另一个进程和线程,假如两个进程同时操作一个共享资源(全局变量),就可能引起问题.
  
   驱动里的互斥主要有两种方法:   信号量 和 自旋锁
    信号量: (休眠了)
        void sema_init (struct semaphore *sem, int val);
        void down(struct semaphore * sem);  //不能在中断上下文使用
        int down_interruptible(struct semaphore * sem)// 能被信号打断
        void up(struct semaphore * sem);
   总结: 1. 可以长期加锁
           2. 只能用于进程上下文,不能用于中断
           3. 持有自旋锁时不能持有信号量
    自旋锁: (忙等待)
       
 spin_lock_init(lock)
        spin_lock(lock)
        spin_unlock(lock)

为了防止得到锁的代码在执行时收到本地中断的影响需要用到自旋锁衍生函数

        spin_lock_irqsave
        spin_lock_irqrestore
    总结: 1. 进程获得自旋锁后 copy_to_user copy_from_user kmalloc 这类有可能引起阻塞的函数都不能调用
            2.  短期加锁
            3.  系统开销大
            4.  持有自旋锁时不能持有信号量 也不能第二次持有(死锁)
    原子操作:
        原子整数操作
     int i = 7;
           i++; //此操作cpu执行三个操作  获得 i的值  计算 7+1 =8  将8写回到i中

      atomic.h
     atomic_t u = ATOMIC_INT(4);
     atomic_add (2+&u);

   原子位操作:
     test_and_set_bit(int nr ,void *addr)

               原子设置 所指向对象的第nr位,并返回原先的值


同步:

wait_event(queue,condition);

wait_event_interruptible(queue,condition);

如果condition不满足继续休眠

wake_up_interruptible (wait_queue_head_t *q);
   唤醒 q 指定的注册在等待队列上的进程。该函数不能直接的立即唤醒进程,而是由调度程序转换上下文,调整为可运行状态。

延时的话可以用schedule_timeout(1) 代替msleep(1);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值