<dfn id="is4kg"></dfn>
  • <ul id="is4kg"></ul>
  • <abbr id="is4kg"></abbr>
  • <ul id="is4kg"></ul>
    <bdo id="is4kg"></bdo>

    曙海教育集團(tuán)論壇Linux專區(qū)Linux驅(qū)動開發(fā) → 深入淺出Linux設(shè)備驅(qū)動之并發(fā)控制(2)


      共有8875人關(guān)注過本帖樹形打印

    主題:深入淺出Linux設(shè)備驅(qū)動之并發(fā)控制(2)

    美女呀,離線,留言給我吧!
    wangxinxin
      1樓 個(gè)性首頁 | 博客 | 信息 | 搜索 | 郵箱 | 主頁 | UC


    加好友 發(fā)短信
    等級:青蜂俠 帖子:1393 積分:14038 威望:0 精華:0 注冊:2010-11-12 11:08:23
    深入淺出Linux設(shè)備驅(qū)動之并發(fā)控制(2)  發(fā)帖心情 Post By:2010-11-24 11:46:56

    下面進(jìn)入對并發(fā)控制的實(shí)戰(zhàn)。首先,在globalvar的驅(qū)動程序中,我們可以通過信號量來控制對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)
    {
     //獲得信號量
     if (down_interruptible(&sem))
     {
      return - ERESTARTSYS;
     }

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

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

     return sizeof(int);
    }

    ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off)
    {
     //獲得信號量
     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;
     }

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

    module_init(globalvar_init);
    module_exit(globalvar_exit);

      接下來,我們給globalvar的驅(qū)動程序增加open()和release()函數(shù),并在其中借助自旋鎖來保護(hù)對全局變量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ū)動程序的效果,我們啟動兩個(gè)進(jìn)程分別打開/dev/globalvar。在兩個(gè)終端中調(diào)用./globalvartest.o測試程序,當(dāng)一個(gè)進(jìn)程打開/dev/globalvar后,另外一個(gè)進(jìn)程將打開失敗,輸出"device open failure",如下圖:

    圖片點(diǎn)擊可在新窗口打開查看
    輸出結(jié)果

    支持(0中立(0反對(0單帖管理 | 引用 | 回復(fù) 回到頂部

    返回版面帖子列表

    深入淺出Linux設(shè)備驅(qū)動之并發(fā)控制(2)








    簽名
    主站蜘蛛池模板: 免费一级毛片不卡不收费| 亚洲国产成人九九综合| 亚洲精品无码久久毛片| 又黄又爽一线毛片免费观看 | 在线观看精品视频一区二区三区| 国产精品国产精品国产专区不卡 | 天天综合天天综合色在线| 成人永久福利免费观看| 天天爽夜夜爽人人爽| 国产精品久久久久电影| 国产丰满岳乱妇在线观看| 国产在线观看精品香蕉v区| 国产第一页在线播放| 国产乱子伦精品免费无码专区| 免费高清在线爱做视频| 亚洲国产欧美另类va在线观看| 久久久精品国产免大香伊 | 久久人妻少妇嫩草av蜜桃| аⅴ天堂中文在线网| 麻豆网神马久久人鬼片| 精品久久久久久中文字幕人妻最新| 欧美日本高清在线不卡区| 护士又湿又紧我要进去了| 无码天堂va亚洲va在线va| 夜夜精品视频一区二区| 国产成人综合精品一区| 国产又大又粗又硬又长免费| 国产午夜手机精彩视频| 人妻少妇精品无码专区二区| 亚洲激情成人网| 久久精品免费一区二区三区| 9lporm自拍视频在线| 美国一级毛片免费| 欧美www网站| 好爽快点使劲深点好紧视频| 国产成人啪精品视频免费网| 国产亚洲欧美久久久久| 亚洲自偷自偷在线制服| 久久国产乱子伦精品在| 东京道一本热中文字幕| aaaaaaa一级毛片|