30 spinlock_t自旋锁和semaphore信号量
来源:互联网 发布:人工智能在线观看 编辑:程序博客网 时间:2024/05/18 19:41
自旋锁是一直循环检查, 直到锁上为止(锁不上也不会让进程休眠)。自旋锁只有两种状态,可锁上和锁不上. 锁上后确保执行的代码为原子操作, 直到解锁为止. 注意不能长时间锁上自旋锁, 不能在临界区里休眠.
spinlock_t 自旋锁 #include <linux/spinlock.h>spinlock_t mylock;spin_lock_init(&mylock); //初始化自旋锁, 初始化过后是可锁上状态.上锁: spin_lock(&mylock); //spin_lock_irq 不让中断打断执行 ... 保护执行的代码 //临界区, 在临界区里不能执行会休眠的代码 ... spin_unlock(&mylock); //spin_unlock_irq
当自旋锁锁上后, 拥有此锁的进程不能进入休眠. 自旋锁只适用于保护执行时间较短的代码.
//////
如用于前面的计数例子.
test.c
#include <linux/init.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/miscdevice.h>#include <linux/sched.h>#include <asm/current.h>#include <linux/spinlock.h>int count = 0;spinlock_t mylock;ssize_t myread(struct file *fl, char __user *buf, size_t len, loff_t *off){ printk("pid = %d, %s, count = %d\n", current->pid, current->comm, count); return 0;}ssize_t mywrite(struct file *fl, const char __user *buf, size_t len, loff_t *off){ spin_lock(&mylock); count++; //保护对count变量的操作. spin_unlock(&mylock); return len; //表示写操作成功}struct file_operations fops = { .owner = THIS_MODULE, .read = myread, .write = mywrite,};struct miscdevice mymdev = { .minor = MISC_DYNAMIC_MINOR, .name = "mymdev", .fops = &fops,};static int __init test_init(void){ spin_lock_init(&mylock); return misc_register(&mymdev);}static void __exit test_exit(void){ misc_deregister(&mymdev);}module_init(test_init);module_exit(test_exit);MODULE_LICENSE("GPL");
//////////////////////////////////////////////////////////////
信号量, 当锁不上时, 当前进程会进入睡眠状态, 直到被up唤醒为止.
信号量可用于生产/消费的模型. 信号量的状态可有多种,一个锁可被锁上多次, 只要有资源都可以上锁.
#include <linux/semaphore.h>struct semaphore { spinlock_t lock; //用于保护对count, wait_list的操作 unsigned int count; //当锁上时,count的值减1. 当解锁时,count的值加1. 如count的值为10表示此锁可被锁上10次. //count的值当大于0时表示可锁, 等于0时表示没有资源分配(不可以锁上,再锁的话, 进程会被安排进入休眠) struct list_head wait_list; //等待操作进程的链表};void sema_init(struct semaphore *sem, int val);//初始化信号量,count成员的值设为valvoid down(struct semaphore *sem); //上锁 count--int down_interruptible(struct semaphore *sem); //能被中断信号打断的上锁int down_trylock(struct semaphore *sem);int down_timeout(struct semaphore *sem, long jiffies); // down_timeout(&sem, HZ);void up(struct semaphore *sem); //解锁 count++
////////////
如用信号量实现生产/消费的模型. 一个进程读取驱动里的数据(消费), 另一个进程写入数据到驱动(生产).在驱动源码里把写入的数据用内核存放起来,当读进程获取数据后,还需从内核链表里移除数据.
test.c
#include <linux/init.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/miscdevice.h>#include <linux/sched.h>#include <asm/current.h>#include <linux/spinlock.h>#include <linux/semaphore.h>#include <linux/slab.h>#include <asm/uaccess.h>spinlock_t mylock; //用于保护链表的操作struct semaphore sem;static LIST_HEAD(dlist); //用于存放数据的链表typedef struct { char data[1000]; int len; struct list_head list;}data_t;ssize_t myread(struct file *fl, char __user *buf, size_t len, loff_t *off){ int ret; data_t *data; struct list_head *tmp; ret = down_interruptible(&sem); if (ret < 0) return -ERESTART; tmp = dlist.next; if (tmp == &dlist) return -ENODATA; data = container_of(tmp, data_t, list); ret = copy_to_user(buf, data->data, data->len); ret = data->len - ret; spin_lock(&mylock); list_del(tmp); spin_unlock(&mylock); kfree(data); printk("after down: pid = %d, %s\n", current->pid, current->comm); return ret;}ssize_t mywrite(struct file *fl, const char __user *buf, size_t len, loff_t *off){ data_t *data = kzalloc(sizeof(data_t), GFP_KERNEL); int ret; ret = copy_from_user(data->data, buf, len); data->len = len-ret; spin_lock(&mylock); list_add_tail(&data->list, &dlist); spin_unlock(&mylock); up(&sem); // count++; return len; }struct file_operations fops = { .owner = THIS_MODULE, .read = myread, .write = mywrite,};struct miscdevice mymdev = { .minor = MISC_DYNAMIC_MINOR, .name = "mymdev", .fops = &fops,};static int __init test_init(void){ sema_init(&sem, 0); //初始化count的值为0 spin_lock_init(&mylock); return misc_register(&mymdev);}static void __exit test_exit(void){ misc_deregister(&mymdev);}module_init(test_init);module_exit(test_exit);MODULE_LICENSE("GPL");
阅读全文
0 0
- 30 spinlock_t自旋锁和semaphore信号量
- 锁机制:自旋锁spinlock和信号量semaphore
- 信号量和自旋锁
- 信号量和自旋锁
- 信号量和自旋锁
- 信号量和自旋锁
- 信号量和自旋锁
- 信号量和自旋锁
- 信号量和自旋锁
- 自旋锁和信号量
- 自旋锁和信号量
- 自旋锁和信号量
- 自旋锁和信号量
- 自旋锁和信号量
- 自旋锁和信号量
- 自旋锁和信号量
- 自旋锁和信号量
- 信号量 和 自旋锁
- 高并发下CURL请求缓慢原因及解决方…
- PHP可控制并发数的异步并发CURL
- SocketIO总结
- 科学家制作出首张黑洞相片的猜想
- mysql什么时候支持反向索引?
- 30 spinlock_t自旋锁和semaphore信号量
- sphinx的实时索引
- mysql集成的key-value引擎-个人翻…
- Gearman Manager安装及碰到的问题
- Gearman Manager调试
- JAVA后台判断是否重复(编辑)
- activiti拿取 当前任务的下一个节点
- Gearman 任务mysql持久化
- 看到google glass和google&nb…