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

以文本方式查看主題

-  曙海教育集團論壇  (http://www.rfoamep.cn/bbs/index.asp)
--  Linux驅動開發  (http://www.rfoamep.cn/bbs/list.asp?boardid=33)
----  深入淺出Linux設備驅動之并發控制(2)  (http://www.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欧美一区二区三区
日韩理论片在线观看| 日韩一区二区三区视频| 国产毛片一区二区| 一区二区三区国产豹纹内裤在线| 欧美日韩在线三区| 色综合视频一区二区三区高清| 91麻豆高清视频| 国产美女精品人人做人人爽| 日韩精品一卡二卡三卡四卡无卡| 国产精品免费aⅴ片在线观看| 日韩精品专区在线| 欧美日韩一本到| 欧美亚洲另类激情小说| 亚洲一区二区三区精品在线观看| 久久久久久久久久久久久久一区| 国产成人精品免费视频大全最热| 91麻豆精品视频| 99精品国产高清一区二区| 99热在这里有精品免费| 免费观看成人av| 天天爽夜夜爽夜夜爽精品视频| 亚洲永久精品大片| 亚洲欧美另类久久久精品| 国产精品久久久久aaaa| 国产精品第一页第二页第三页| 久久精品人人做人人爽人人| 欧美日韩成人综合| 69堂成人精品免费视频| 欧美一区二区三区啪啪| 欧美草草影院在线视频| 日韩精品在线网站| 欧美绝品在线观看成人午夜影视| 欧美日韩精品欧美日韩精品| 欧美男生操女生| 日韩欧美不卡在线观看视频| 日韩欧美国产电影| 精品国产乱码久久久久久蜜臀| 欧美成人aa大片| 国产精品欧美久久久久一区二区| 国产精品麻豆99久久久久久| 亚洲精品你懂的| 香蕉影视欧美成人| 捆绑变态av一区二区三区| 国产精品77777竹菊影视小说| 懂色av中文字幕一区二区三区| 99精品久久99久久久久| 精品乱子伦一区二区三区| 欧美一区二区三区四区夜夜大片 | 91网免费观看| 国产91视觉| 亚洲 日韩 国产第一区| 欧美三级日韩三级| 26uuu国产一区二区三区| 中文字幕一区二区三区色视频| 国产喂奶挤奶一区二区三区| 亚洲精品国产一区二区精华液| 日韩福利电影在线观看| 国产精品99久久久久久宅男| 国产成人精品福利一区二区三区| 新呦u视频一区二区| 8x福利精品第一导航| 国产日产欧产精品推荐色 | 欧美三级蜜桃2在线观看| 久久影音资源网| 亚洲香肠在线观看| 国v精品久久久网| 精品午夜一区二区| 欧美日韩亚洲综合在线 | 久久国产夜色精品鲁鲁99| 丰满少妇久久久久久久| 欧美凹凸一区二区三区视频 | 丁香婷婷综合五月| 免费日韩av电影| 在线不卡免费欧美| 一区二区三区免费看视频| 精品中文av资源站在线观看| 成人av中文| 色老头久久综合| 国产精品区一区二区三| 蜜芽一区二区三区| 国产欧美韩日| 日韩一区二区在线观看视频| 一区二区三区久久| 91论坛在线播放| 欧美日韩视频在线一区二区| 亚洲成人三级小说| 日韩国产欧美精品| 亚洲色图在线播放| 国产伦精品一区二区三区四区视频 | 日本成人中文字幕在线视频| 欧美久久在线| 国产精品国产三级国产a| 99久久国产免费看| 欧美电影免费观看高清完整版| 奇米影视7777精品一区二区| 日韩av一区二区三区在线| 亚洲欧美偷拍卡通变态| 韩国精品一区二区三区六区色诱| 久久亚洲精华国产精华液| 国产精品99久| 91精品国产91热久久久做人人 | 成人欧美一区二区三区在线播放| 91一区在线观看| 久久香蕉国产线看观看99| 成人国产亚洲欧美成人综合网| 91精品久久久久久蜜臀| 国产精品18久久久久久vr | 国产亚洲综合色| 51国偷自产一区二区三区| 2022国产精品视频| 91啪亚洲精品| 国产欧美日韩精品在线| 超碰97国产在线| 亚洲欧洲av一区二区三区久久| 精品一区二区三区国产| 亚洲一二三四区| 色综合中文字幕国产| 日本午夜精品视频在线观看| 日本在线免费观看一区| 经典三级在线一区| 久久精品一区二区三区不卡免费视频| 91蜜桃传媒精品久久久一区二区| 91麻豆精品国产91久久久资源速度| 91精品免费在线| 国产乱子轮精品视频| 欧美一区二视频| 成人伦理片在线| 久久久国产精品午夜一区ai换脸| 99一区二区| 亚洲欧美一区二区三区极速播放| 欧美一区二区影视| 国内视频一区| 亚洲一区二区三区中文字幕在线| 91福利视频网站| 成人免费观看av| 中文字幕一区不卡| 亚洲一区二区精品在线观看| 毛片av一区二区| 精品久久久久av影院| 国产一区二区三区四区五区在线 | 99久久精品国产毛片| 国产精品毛片久久久久久久| 少妇免费毛片久久久久久久久| 麻豆精品视频在线观看免费| 日韩视频一区在线观看| 国产伦精品一区二区三区四区视频| 亚洲自拍偷拍av| 欧美久久一二三四区| 999视频在线观看| 欧美a一区二区| 国产视频一区二区在线| 亚洲一区二区三区色| 粉嫩aⅴ一区二区三区四区 | 亚洲精品日日夜夜| 欧美日韩一区二区欧美激情| 99国产精品一区| 欧美日韩国产一区二区三区地区| 成人黄色免费短视频| 亚洲一区av在线| 亚洲精品一区在线观看| 亚洲精品在线免费| 成人91在线观看| 亚洲福利国产精品| 精品国产一区二区三区忘忧草 | 亚洲国产精品嫩草影院| 日韩欧美一区电影| 欧美日韩一区二区三区免费| 国内精品写真在线观看| 亚洲欧美综合另类在线卡通| 欧美中文一区二区三区| 国产高清不卡av| 国产剧情一区在线| 最近中文字幕一区二区三区| 欧美性大战久久| 精品国产乱码久久久久久蜜柚| 美女视频黄 久久| 中文字幕在线一区| 在线综合+亚洲+欧美中文字幕| 欧美大陆一区二区| 91在线国产观看| 蜜臀精品一区二区三区在线观看| 国产精品久久免费看| 欧美一级欧美一级在线播放| 日韩影片在线播放| 91麻豆蜜桃| 国产69精品久久777的优势| 日本中文字幕一区二区有限公司| 国产精品久久久久久久久果冻传媒| 欧美一卡在线观看| 欧美手机在线视频| 亚洲欧洲精品一区二区三区波多野1战4 | 欧美日韩视频在线一区二区 | 日本一区二区不卡高清更新| 99国产精品国产精品久久| 韩国成人福利片在线播放| 亚洲永久精品大片| 中文字幕亚洲在| 久久久久国产精品厨房| 欧美一区二区精品久久911| 亚洲欧美日韩在线综合|