久久精品在这里_成人99免费视频_国产激情视频一区二区在线观看_国产伦精品一区二区三区免费 _亚洲午夜免费福利视频_色狠狠色狠狠综合_av在线综合网_91毛片在线观看_欧美视频一区二区在线观看_极品美女销魂一区二区三区免费_国产亚洲欧美激情_在线免费观看不卡av_日韩不卡一区二区三区_91精品国产麻豆国产自产在线_亚洲国产精品一区二区久久恐怖片_a4yy欧美一区二区三区

以文本方式查看主題

-  曙海教育集團論壇  (http://m.rfoamep.cn/bbs/index.asp)
--  Linux驅動開發  (http://m.rfoamep.cn/bbs/list.asp?boardid=33)
----  深入淺出Linux設備驅動之并發控制(2)  (http://m.rfoamep.cn/bbs/dispbbs.asp?boardid=33&id=1742)

--  作者:wangxinxin
--  發布時間:2010-11-24 11:46:56
--  深入淺出Linux設備驅動之并發控制(2)
下面進入對并發控制的實戰。首先,在globalvar的驅動程序中,我們可以通過信號量來控制對int global_var的并發訪問,下面給出源代碼:

#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從內核空間復制到用戶空間
 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;
 }

 //將用戶空間的數據復制到內核空間的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的驅動程序增加open()和release()函數,并在其中借助自旋鎖來保護對全局變量int globalvar_count(記錄打開設備的進程數)的訪問來實現設備只能被一個進程打開(必須確保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);

  為了上述驅動程序的效果,我們啟動兩個進程分別打開/dev/globalvar。在兩個終端中調用./globalvartest.o測試程序,當一個進程打開/dev/globalvar后,另外一個進程將打開失敗,輸出"device open failure",如下圖:

圖片點擊可在新窗口打開查看
輸出結果

久久精品在这里_成人99免费视频_国产激情视频一区二区在线观看_国产伦精品一区二区三区免费 _亚洲午夜免费福利视频_色狠狠色狠狠综合_av在线综合网_91毛片在线观看_欧美视频一区二区在线观看_极品美女销魂一区二区三区免费_国产亚洲欧美激情_在线免费观看不卡av_日韩不卡一区二区三区_91精品国产麻豆国产自产在线_亚洲国产精品一区二区久久恐怖片_a4yy欧美一区二区三区
亚洲欧美一区二区视频| 久久精品夜色噜噜亚洲aⅴ| 欧美色图亚洲自拍| 精品国产乱码久久久久久88av | 一本色道久久99精品综合| 一区二区三区av在线| 色天天综合色天天久久| 欧美日韩在线三区| 日韩视频永久免费| 欧美高清在线精品一区| 亚洲影院免费观看| 蜜桃久久av一区| 国产精品一品二品| 91久色国产| 日韩精品电影网站| 欧美一区二区在线免费观看| 911精品国产一区二区在线| 久久精品中文字幕一区二区三区| 亚洲大尺度视频在线观看| 一区二区三区高清不卡| 日韩经典中文字幕一区| 国内精品免费**视频| 成人黄色网址在线观看| 国产精品一区二区三区在线| 亚洲精品视频一二三| 欧美绝品在线观看成人午夜影视| 久久久久成人黄色影片| 亚洲一区二区视频| 丁香桃色午夜亚洲一区二区三区| 国内精品二区| 欧美日韩美少妇| 亚洲国产精品国自产拍av| 日韩成人免费看| 白白色 亚洲乱淫| 婷婷精品国产一区二区三区日韩 | 激情五月激情综合网| 99三级在线| 91国偷自产一区二区使用方法| 精品久久久久av影院| 一区二区高清免费观看影视大全 | 亚洲午夜在线视频| 高清成人免费视频| 欧美裸体网站| 欧美电视剧在线观看完整版| 一区二区在线免费| 99re这里都是精品| 91久久精品一区二区二区| 欧美国产精品一区| 国产高清在线精品| 午夜一区二区三视频在线观看| 欧美大片顶级少妇| 免费观看一级欧美片| 精品一卡二卡三卡四卡日本乱码 | 久久成人av少妇免费| 精品一区久久久久久| 日韩一区二区影院| 蜜桃视频第一区免费观看| 久久99欧美| 久久奇米777| 久99久精品视频免费观看| 欧美日韩在线精品一区二区三区| 欧美成人a在线| 久久精品国产99国产| 日韩av在线电影观看| 欧美激情一区二区在线| 国产精品一区二区91| 中文精品一区二区三区| 亚洲婷婷在线视频| 99国产精品久久久| 欧美一区二区三区在线视频| 日韩av一区二| 日韩中文不卡| 一区二区三区在线视频免费| 国产高清自拍一区| 久久久噜噜噜久噜久久综合| 粉嫩绯色av一区二区在线观看| 欧美专区在线观看一区| 五月综合激情日本mⅴ| 欧美xxxx黑人又粗又长密月| 欧美国产在线观看| 91免费看蜜桃| 久久久影视传媒| 99久久精品免费观看| 91精品国产日韩91久久久久久| 裸体一区二区三区| 在线观看区一区二| 美女在线视频一区| 欧美视频一区二区| 国产一区二区三区免费看| 欧美一区二区三区四区高清| 丝袜诱惑亚洲看片| 日韩欧美视频第二区| 国产精品二区一区二区aⅴ污介绍| jvid福利写真一区二区三区| 精品视频123区在线观看| 婷婷久久综合九色综合绿巨人| 免费在线观看一区二区| 亚洲色图视频网| 欧美国产一区二区在线| 亚洲乱码中文字幕| 精品国产一区二区三| 亚洲视频资源在线| 欧美在线一区二区三区四区| 亚洲精品国产精品乱码不99| 麻豆一区区三区四区产品精品蜜桃| 中文字幕不卡的av| 国产精品加勒比| 亚洲精品ww久久久久久p站| 欧美日韩一区二| 爽好多水快深点欧美视频| 亚洲视频在线二区| 蜜桃一区二区三区四区| 欧美日韩国产首页| 成人在线视频一区二区| wwwwxxxxx欧美| 久久66热这里只有精品| 亚洲高清免费观看 | 亚洲一二三区视频在线观看| 欧美久久久久久一卡四| 一区二区三国产精华液| 亚洲免费在线精品一区| 青青青伊人色综合久久| 91精品国产日韩91久久久久久| 9i看片成人免费高清| 欧美激情在线看| 日韩欧美激情一区二区| 美女爽到高潮91| 日韩免费观看高清完整版在线观看| 91欧美一区二区| 亚洲色图制服丝袜| 日本韩国视频一区二区| 91浏览器在线视频| 久久久国产一区二区三区四区小说| 国产精品对白一区二区三区| 一区二区三区毛片| 欧美色老头old∨ideo| 成人爱爱电影网址| 亚洲欧美成aⅴ人在线观看| 一区二区视频在线观看| 国产91清纯白嫩初高中在线观看| 国产亚洲欧美激情| 亚洲一区二区三区加勒比| 国产一区 二区 三区一级| 中文欧美字幕免费| 一本到三区不卡视频| 成人av电影免费在线播放| 亚洲精品免费视频| 91精品国产全国免费观看| 久久66热这里只有精品| 韩日精品视频一区| 亚洲天天做日日做天天谢日日欢| 欧洲日韩一区二区三区| 国产精品日本一区二区| 精品一区二区三区久久久| 中文字幕一区二区视频| 欧美日韩一级二级| 蜜桃传媒一区二区| 成人自拍视频在线观看| 亚洲一区在线免费观看| 欧美大片在线观看一区二区| 日本一区二区三区精品视频| 成熟亚洲日本毛茸茸凸凹| 亚洲一二三区不卡| 久久亚洲私人国产精品va媚药| 亚洲欧洲一区二区| 99视频在线| 国产真实乱子伦精品视频| 国产精品麻豆网站| 91精品国产乱| 亚洲一区尤物| 国产一区二区三区无遮挡| 国产一区在线不卡| 亚洲伊人伊色伊影伊综合网| 亚洲精品在线观看网站| 在线看不卡av| 日本在线播放不卡| 丁香婷婷久久久综合精品国产| 久久se精品一区二区| 一区二区三区四区不卡在线 | 国产欧美综合在线观看第十页| 在线视频一区二区三| 精品乱码一区| 91美女片黄在线观看91美女| 理论电影国产精品| 97人人模人人爽人人少妇| 蜜桃传媒麻豆第一区在线观看| 伊人性伊人情综合网| 亚洲国产成人午夜在线一区| 日韩欧美视频一区| 欧美日韩精品专区| 午夜欧美一区二区三区免费观看| 国产精品一区二区三区免费| 99久久综合国产精品| 韩国v欧美v亚洲v日本v| 日本aⅴ免费视频一区二区三区| 一区二区三区欧美激情| 欧美在线一区二区| 欧美精品亚洲| 国产精品国产三级欧美二区 | 欧洲色大大久久|