总结一下, 我们写module的时候, 常用的简单的互斥的例子:
以下是个一个例子, 只有一个进程才能打开open() , 其他的进程不可以,直接返回。大家可以比较一下优劣。
------------------------------------------------- 用信号量: static DECLARE_MUTEX(char_sem); static unsigned long char_inuse; static int device_open(struct inode *inode, struct file *file) { static int counter = 0; down_interruptible(&char_sem); if(char_inuse == 1) { up(&char_sem); return -EBUSY; } char_inuse = 1; up(&char_sem); ........... } static int device_release(struct inode *inode, struct file *file) { char_inuse = 0; MOD_DEC_USE_COUNT; return 0; } ----------------------------------- 用原子变量: static atomic_t inuse_atomic = ATOMIC_INIT(-1); /* 这个动作有可能并发,这里我又改成原子变量了 */ static int device_open(struct inode *inode, struct file *file) { if( ! atomic_inc_and_test(&inuse_atomic)) //原子加1 , 并判断是否==0 , -1 , 表示无人使用此设备 { dbg("%d process is opening this device \n",inuse_atomic);//如果值是1 , 说明刚好有一个进程在访问该设备 dbg("open device failure \n"); return -EBUSY; } //try_module_get(THIS_MODULE); MOD_INC_USE_COUNT; return SUCCESS; } static int device_release(struct inode *inode, struct file *file) { atomic_set(&inuse_atomic,-1);//重新再把它置成-1 MOD_DEC_USE_COUNT; return 0; } ------------------------------ 用原子的bit操作 static int chardev_users = 0; //防止互斥, 这里用更严格的test_and_set_bit() 函数 static int device_open(struct inode *inode, struct file *file) { static int counter = 0; // if (Device_Open) // return -EBUSY; // Device_Open++; // 上面的办法太不可靠了。用原子操作或者bit操作才是最可靠的。 if(test_and_set_bit(0,&chardev_users)) return -EBUSY; //sprintf(msg, "I already told you %d times Hello world!\n", counter++); //memset(msg,'\0',sizeof(msg)); msg_Ptr = msg; //try_module_get(THIS_MODULE); MOD_INC_USE_COUNT; //increase the flag to present the module is used /* strategy : * you should here allocate resources , not in init_module() ,if(refer == 0) */ return SUCCESS; } static int device_release(struct inode *inode, struct file *file) { // Device_Open--; /* We're now ready for our next caller */ //chardev_users =0; //直到现在才可以被别人open() //set_bit() is better by me if( !test_and_clear_bit(0,&chardev_users)) //bit0 should be 1 dbg("It looks wrong ,lock may bad \n"); MOD_DEC_USE_COUNT;
|