驱动程序 | 应用程序 | 备注 | |
自旋锁 | struct spin_lock_t lock; spin_lock_init(&lock); spin_lock(&lock); spin_unlock(&lock) |
| 访问临界资源前上锁, 没抢到锁则阻塞询问不断尝试再次上锁(自旋)。 访问结束后解锁。 |
读写锁 | rwlock_init(lock) read_lock(lock) read_unlock(lock) write_lock(lock) write_unlock(lock) write_trylock(lock) | 读前上读锁,读完后解读锁 写前上写锁,写完后解写锁 | |
互斥锁 | struct mutex lock; mutex_init(lock); mutex_lock(lock); mutex_unlock(lock); | struct pthread_mutex_t lock; pthread_mutex_init(lock); pthread_mutex_lock(lock); pthread_mutex_unlock(lock); | 访问临界资源前上锁, 没抢到锁则阻塞询问 访问结束后解锁 |
等待队列 | struct wait_queue wq; init_wait_queue_head(&wq) wait_event(wq,condition); wait_event_interruptable(wq,condition); wait_event_timeout(wq,condition,timeout); wake_up(wq) | pthread_mutex_t lock; pthread_cond_t cond; pthread_cond_wait(cond,lock); pthread_cond_broadcast(cond);
| 睡在条件上, 条件满足则往下走, 条件不满足则休眠。 会有人叫醒他, 醒来再次判断条件, 若还不满足则继续睡 |
信号量 | struct semaphore sem; sema_init(&sem,val); down(&sem); up(&sem);
| 线程间: sem_t sem; sem_init(&sem,val); sem_wait(&sem); sem_post(&sem); 进程间: 1.上面也可用,配合sem_open() 2.信号灯集PV操作: 【key_t key = ftok(path,int);】 id = semget(key,n,flag); semctl(id,灯编号,SETVAL,0); struct sembuf P ={ .sem_num = 灯编号 .sem_op = -1;//P减1,V加1 .sem_flg = 阻塞/非阻塞 } semop(id,P,操作次数); semop(id,V,操作次数);
| 大家在看红绿灯, 红灯停绿灯行, 人人遵守则同步问题迎刃而解
对val减1后判断 val值等于0则阻塞,大于0则往下走 做完自己的事后又将val加1以便别人不等红灯 |
原子操作 | atomic_t v = ATOMIC_INIT(val); atomic_read(v); atomic_set(v,val); atomic_add_return(i,v); atomic_sub_and_test(i,v); atomic_dec_and_test(v); | 通过一系列的加减、自增自减、判断非零等操作 手工模拟出PV操作的过程,实现同步互斥。
这些函数的核心意义是: 多个任务同时对原子量v进行加减查操作时, 只要是调用这些原子操作函数实现的, 就不用担心竞态的问题, 这些函数内部已经做好了防冲突的机制。 |
字符设备驱动第八课---运用程序与驱动程序同步与互斥机制的对比
最新推荐文章于 2021-09-02 19:01:54 发布