總結(jié)一下, 我們寫module的時候, 常用的簡單的互斥的例子:
注意 ,我這三個例子, 都是在2.4.24 kernel下測試的, 如果要用在2.6上,可能需要做相應(yīng)的更改和調(diào)整, 自己改好以后, 貼上來!
以下是個一個例子, 只有一個進程才能打開open() , 其他的進程不可以,直接返回。大家可以比較一下優(yōu)劣。
用信號量:
static DECLARE_MUTEX(char_sem);//2.6 kernel: static DEFINE_MUTEX(rtc_mutex);
static unsigned long char_inuse;
static int device_open(struct inode *inode, struct file *file)
{
static int counter = 0;
down_interruptible(&char_sem);//2.6 kernel: mutex_lock(&char_mutex);
if(char_inuse == 1) {
up(&char_sem);
return -EBUSY;
}
char_inuse = 1;
up(&char_sem);//2.6 kernel: mutex_unlock(&char_sem);
try_module_get(THIS_MODULE);
...........
}
static int device_release(struct inode *inode, struct file *file)
{
char_inuse = 0;
module_put(THIS_MODULE);
return 0;
}
用原子變量:
static atomic_t inuse_atomic = ATOMIC_INIT(-1);
/* 這個動作有可能并發(fā),這里我又改成原子變量了
*/
static int device_open(struct inode *inode, struct file *file)
{
if( ! atomic_inc_and_test(&inuse_atomic)) //原子加1 , 并判斷是否==0 , -1 , 表示無人使用此設(shè)備
{
dbg("%d process is opening this device \n",inuse_atomic);//如果值是1 , 說明剛好有一個進程在訪問該設(shè)備
dbg("open device failure \n");
return -EBUSY;
}
//try_module_get(THIS_MODULE);//2.6 kernel
try_module_get(THIS_MODULE);
return SUCCESS;
}
static int device_release(struct inode *inode, struct file *file)
{
atomic_set(&inuse_atomic,-1);//重新再把它置成-1
module_put(THIS_MODULE);
return 0;
}
用原子的bit操作
static int chardev_users = 0; //防止互斥, 這里用更嚴(yán)格的test_and_set_bit() 函數(shù)
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);
try_module_get(THIS_MODULE); //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; //直到現(xiàn)在才可以被別人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");
module_put(THIS_MODULE);
}
也就是說,需要特別注意的就是讀取模塊和刪除模塊的時候,需要分別注意下,這兩個進程是否進行了互斥操作來避免發(fā)生錯誤!
posted on 2010-03-07 02:08
deercoder 閱讀(521)
評論(0) 編輯 收藏 引用 所屬分類:
Unix/Linux