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

Rss & SiteMap

曙海教育集團論壇 http://www.bjzhda.cn

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

標題:深入淺出Linux設備驅動之并發(fā)控制(2)

1樓
wangxinxin 發(fā)表于:2010-11-24 11:46:56
下面進入對并發(fā)控制的實戰(zhàn)。首先,在globalvar的驅動程序中,我們可以通過信號量來控制對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從內核空間復制到用戶空間
 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ù)復制到內核空間的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()函數(shù),并在其中借助自旋鎖來保護對全局變量int globalvar_count(記錄打開設備的進程數(shù))的訪問來實現(xià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);

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

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

Copyright © 2000 - 2009 曙海教育集團
Powered By 曙海教育集團 Version 2.2
Processed in .01563 s, 2 queries.
久久精品在这里_成人99免费视频_国产激情视频一区二区在线观看_国产伦精品一区二区三区免费 _亚洲午夜免费福利视频_色狠狠色狠狠综合_av在线综合网_91毛片在线观看_欧美视频一区二区在线观看_极品美女销魂一区二区三区免费_国产亚洲欧美激情_在线免费观看不卡av_日韩不卡一区二区三区_91精品国产麻豆国产自产在线_亚洲国产精品一区二区久久恐怖片_a4yy欧美一区二区三区
水蜜桃亚洲精品| 亚洲国产视频在线| 色老头久久综合| 一区二区在线观| 亚洲黄色一区二区三区| 日韩激情视频| 一道精品一区二区三区| 最近看过的日韩成人| 一区二区三区四区视频在线| 在线观看日韩片| 欧美专区日韩专区| 91精品欧美一区二区三区综合在 | 亚洲最大成人网4388xx| 亚洲人精品午夜| 亚洲国产成人av网| 国产一区二区三区美女| 99精品偷自拍| 久久精品国产精品国产精品污| 免费看成人午夜电影| 综合久久国产| 精品美女一区二区| 亚洲天堂中文字幕| 日本美女视频一区二区| 成人永久看片免费视频天堂| 国产精品区一区二区三在线播放| 欧洲在线视频一区| 欧美亚洲丝袜传媒另类| 久久众筹精品私拍模特| 亚洲精品视频在线观看免费| 久久精品国产一区二区三| 成人永久看片免费视频天堂| 国产精品永久入口久久久| 一本色道久久综合亚洲二区三区| 欧美一区二区三区思思人| 亚洲欧洲三级电影| 国内精品久久久久影院一蜜桃| 99久久自偷自偷国产精品不卡| 亚洲一区三区视频在线观看| 欧美一区二区三区思思人| 亚洲女与黑人做爰| 国产一区二区三区免费| 快播亚洲色图| 日韩欧美一级特黄在线播放| 一级中文字幕一区二区| 国产a视频精品免费观看| 好吊色欧美一区二区三区四区| 中文字幕一区二区三区最新| xvideos.蜜桃一区二区| 香蕉久久一区二区不卡无毒影院| 成人免费视频一区| 一区二区视频在线播放| 欧美激情一区在线| 国内精品第一页| 日本不卡久久| 26uuu亚洲综合色欧美| 天天亚洲美女在线视频| 成人影片在线播放| 欧美日韩中文国产| 一区二区三区四区激情| 1卡2卡3卡精品视频| 欧美日韩精品三区| 亚洲一区二区三区中文字幕在线| 99国产精品国产精品久久| 中日韩在线视频| 国产精品国产精品国产专区不片| 国产一区二区三区蝌蚪| 亚洲精品一区二区三区樱花 | 欧美精品vⅰdeose4hd| 亚洲精品免费一二三区| 99久久99精品久久久久久| 欧美午夜电影在线播放| 一级特黄大欧美久久久| av资源一区二区| 日韩视频免费直播| 精品一区二区三区香蕉蜜桃 | 欧美日韩一卡二卡三卡| 一区二区三区加勒比av| av综合在线播放| 欧美日韩在线亚洲一区蜜芽| 一区二区三区色| 国产欧美丝袜| 久久精品夜色噜噜亚洲aⅴ| 精品一区二区影视| 色综合久久久网| 亚洲国产aⅴ天堂久久| 精品欧美日韩在线| 国产精品国产自产拍在线| 999国内精品视频在线| 欧美r级在线观看| 国产suv精品一区二区6| 69堂国产成人免费视频| 日韩av在线播放中文字幕| 亚洲不卡1区| 亚洲图片欧美色图| 日韩欧美一区二区视频在线播放| 亚洲美女在线一区| 免费看国产精品一二区视频| 亚洲丝袜另类动漫二区| 精品卡一卡二| 中文字幕一区av| 欧美国产视频在线观看| 亚洲日本成人在线观看| 欧美日本韩国一区二区三区| 亚洲精品国产一区二区三区四区在线| 国产精品久久亚洲7777| 国产精品国产自产拍高清av | 国产亚洲精品bt天堂精选| 国产98色在线|日韩| 91精品国产色综合久久不卡蜜臀| 国产在线观看一区二区| 91精品一区二区三区久久久久久| 国产成人综合亚洲网站| 欧美成人一区二区三区在线观看| 成人av电影在线网| 中文字幕高清一区| 欧美一级二级三级| 天天综合网天天综合色| 欧美制服丝袜第一页| 久久91精品久久久久久秒播| 欧美一级免费观看| 91一区一区三区| 亚洲少妇30p| 在线不卡视频一区二区| 国产一区亚洲一区| 久久精品一二三| 日韩av图片| 国产一区二区三区电影在线观看 | 亚洲精品国产第一综合99久久 | 欧美日韩精品欧美日韩精品一综合| 国产乱码精品一区二区三区av | 欧美成人女星排行榜| 91中文字精品一区二区| 亚洲视频免费在线| 色婷婷av一区| 成人av免费在线播放| 日韩理论电影院| 在线看日韩精品电影| www.日韩av| 亚洲免费观看高清完整版在线观看熊| 一本一本a久久| 成人av免费在线| 亚洲国产日韩a在线播放| 欧美美女一区二区| 成人在线免费网站| 奇米一区二区三区av| 精品国产凹凸成av人网站| 国产在线一区二区三区四区| 全国精品久久少妇| 久久精品日产第一区二区三区高清版| 欧美激情第一页在线观看| 国内精品久久久久影院薰衣草 | 舔着乳尖日韩一区| 日韩欧美一区二区久久婷婷| 久久久一本精品99久久精品| 久久99热这里只有精品| 国产日韩av一区| 欧美亚洲综合色| 精品欧美一区二区久久久伦| 经典三级在线一区| 中文字幕制服丝袜成人av | 亚洲国产视频一区二区| 日韩西西人体444www| 欧美日韩在线一区二区三区| 精品一区二区三区在线播放视频| 中文字幕欧美日本乱码一线二线 | 亚洲.欧美.日本.国产综合在线 | 国产一区二区免费视频| 日韩一区日韩二区| 日韩欧美你懂的| 伊人av成人| 玖玖玖精品中文字幕| 成人免费视频app| 奇米四色…亚洲| 成人欧美一区二区三区小说| 欧美日韩国产a| 日韩在线观看电影完整版高清免费| 成人av在线播放网址| 日本视频一区二区| 亚洲精品成人精品456| 久久综合色综合88| 欧美日韩成人高清| 一区二区三区四区不卡| 精品视频在线观看| 91在线视频免费观看| 国内精品在线播放| 日本中文字幕一区二区视频| 亚洲欧美区自拍先锋| 国产欧美一区二区在线| 欧美日韩高清影院| 亚洲欧美精品| 国产亚洲第一区| 成人妖精视频yjsp地址| 久久99精品久久久| 性欧美大战久久久久久久久| 国产精品高潮呻吟| 国产三级精品在线| 国产亚洲综合av| 久久亚洲免费视频| 欧美精品一区二| 26uuu亚洲综合色|