欧美日韩一区二区高清,久久视频这里只有精品,超黄网站在线观看,成人av影院在线观看

Rss & SiteMap

曙海教育集團(tuán)論壇 http://www.bjzhda.cn

曙海教育集團(tuán)論壇
共1 條記錄, 每頁顯示 10 條, 頁簽: [1]
[瀏覽完整版]

標(biāo)題:深入淺出Linux設(shè)備驅(qū)動(dòng)之并發(fā)控制(2)

1樓
wangxinxin 發(fā)表于:2010-11-24 11:46:56
下面進(jìn)入對(duì)并發(fā)控制的實(shí)戰(zhàn)。首先,在globalvar的驅(qū)動(dòng)程序中,我們可以通過信號(hào)量來控制對(duì)int global_var的并發(fā)訪問,下面給出源代碼:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
MODULE_LICENSE("GPL");

#define MAJOR_NUM 254

static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*);
static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);

struct file_operations globalvar_fops =
{
 read: globalvar_read, write: globalvar_write,
};
static int global_var = 0;
static struct semaphore sem;

static int __init globalvar_init(void)
{
 int ret;
 ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops);
 if (ret)
 {
  printk("globalvar register failure");
 }
 else
 {
  printk("globalvar register success");
  init_MUTEX(&sem);
 }
 return ret;
}

static void __exit globalvar_exit(void)
{
 int ret;
 ret = unregister_chrdev(MAJOR_NUM, "globalvar");
 if (ret)
 {
  printk("globalvar unregister failure");
 }
 else
 {
  printk("globalvar unregister success");
 }
}

static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
 //獲得信號(hào)量
 if (down_interruptible(&sem))
 {
  return - ERESTARTSYS;
 }

 //將global_var從內(nèi)核空間復(fù)制到用戶空間
 if (copy_to_user(buf, &global_var, sizeof(int)))
 {
  up(&sem);
  return - EFAULT;
 }

 //釋放信號(hào)量
 up(&sem);

 return sizeof(int);
}

ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off)
{
 //獲得信號(hào)量
 if (down_interruptible(&sem))
 {
  return - ERESTARTSYS;
 }

 //將用戶空間的數(shù)據(jù)復(fù)制到內(nèi)核空間的global_var
 if (copy_from_user(&global_var, buf, sizeof(int)))
 {
  up(&sem);
  return - EFAULT;
 }

 //釋放信號(hào)量
 up(&sem);
 return sizeof(int);
}

module_init(globalvar_init);
module_exit(globalvar_exit);

  接下來,我們給globalvar的驅(qū)動(dòng)程序增加open()和release()函數(shù),并在其中借助自旋鎖來保護(hù)對(duì)全局變量int globalvar_count(記錄打開設(shè)備的進(jìn)程數(shù))的訪問來實(shí)現(xiàn)設(shè)備只能被一個(gè)進(jìn)程打開(必須確保globalvar_count最多只能為1):

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>

MODULE_LICENSE("GPL");

#define MAJOR_NUM 254

static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*);
static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);
static int globalvar_open(struct inode *inode, struct file *filp);
static int globalvar_release(struct inode *inode, struct file *filp);

struct file_operations globalvar_fops =
{
 read: globalvar_read, write: globalvar_write, open: globalvar_open, release:
globalvar_release,
};

static int global_var = 0;
static int globalvar_count = 0;
static struct semaphore sem;
static spinlock_t spin = SPIN_LOCK_UNLOCKED;

static int __init globalvar_init(void)
{
 int ret;
 ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops);
 if (ret)
 {
  printk("globalvar register failure");
 }
 else
 {
  printk("globalvar register success");
  init_MUTEX(&sem);
 }
 return ret;
}

static void __exit globalvar_exit(void)
{
 int ret;
 ret = unregister_chrdev(MAJOR_NUM, "globalvar");
 if (ret)
 {
  printk("globalvar unregister failure");
 }
 else
 {
  printk("globalvar unregister success");
 }
}

static int globalvar_open(struct inode *inode, struct file *filp)
{
 //獲得自選鎖
 spin_lock(&spin);

 //臨界資源訪問
 if (globalvar_count)
 {
  spin_unlock(&spin);
  return - EBUSY;
 }
 globalvar_count++;

 //釋放自選鎖
 spin_unlock(&spin);
 return 0;
}

static int globalvar_release(struct inode *inode, struct file *filp)
{
 globalvar_count--;
 return 0;
}

static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t
*off)
{
 if (down_interruptible(&sem))
 {
  return - ERESTARTSYS;
 }
 if (copy_to_user(buf, &global_var, sizeof(int)))
 {
  up(&sem);
  return - EFAULT;
 }
 up(&sem);
 return sizeof(int);
}

static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len,
loff_t *off)
{
 if (down_interruptible(&sem))
 {
  return - ERESTARTSYS;
 }
 if (copy_from_user(&global_var, buf, sizeof(int)))
 {
  up(&sem);
  return - EFAULT;
 }
 up(&sem);
 return sizeof(int);
}

module_init(globalvar_init);
module_exit(globalvar_exit);

  為了上述驅(qū)動(dòng)程序的效果,我們啟動(dòng)兩個(gè)進(jìn)程分別打開/dev/globalvar。在兩個(gè)終端中調(diào)用./globalvartest.o測(cè)試程序,當(dāng)一個(gè)進(jìn)程打開/dev/globalvar后,另外一個(gè)進(jìn)程將打開失敗,輸出"device open failure",如下圖:

圖片點(diǎn)擊可在新窗口打開查看
輸出結(jié)果
共1 條記錄, 每頁顯示 10 條, 頁簽: [1]

Copyright © 2000 - 2009 曙海教育集團(tuán)
Powered By 曙海教育集團(tuán) Version 2.2
Processed in .01563 s, 2 queries.
主站蜘蛛池模板: 库尔勒市| 常宁市| 夏津县| 苍南县| 英超| 临朐县| 金川县| 宁安市| 曲阜市| 东平县| 新巴尔虎左旗| 双柏县| 忻城县| 如东县| 三江| 六盘水市| 根河市| 邛崃市| 嘉黎县| 神木县| 绩溪县| 盐亭县| 武山县| 卫辉市| 郧西县| 浮梁县| 昭通市| 延安市| 道孚县| 化德县| 博野县| 大英县| 旅游| 镇远县| 漠河县| 湖南省| 抚松县| 石门县| 凌海市| 遂平县| 高陵县|