Linux_信号量使用实例详解

来源:互联网 发布:合肥网络教育学校 编辑:程序博客网 时间:2024/05/16 02:28

实例篇:1.定义带有设备并发控制方案的结构体(诸如信号量,自旋锁等,反正前边那么多了)

我是一名高手,告诉大家一个高手的习惯,就是喜欢也习惯把将某设备所使用的自旋锁,信号量等辅助手段也放到设备结构体中,就像下边这样:

struct csyncontrol_dev
{
    struct cdev cdev;//cdev结构体
    unsigned char mem[CSYNCONTROL_SIZE]; //设备内存
    struct semaphore sem;  //用于并发控制的信号量
}
然后,将信号量的初始化工作放到模块初始化部分里

int csycontrol_init(void)
{
    int result;
    dev_t devno = MKDEV(global_major,0);
   
    //申请设备号
     XXXXXX(参照前边Linux设备驱动之简单字符设备驱动(下))
    csycontrol_setup_cdev(csyncontrol_devp, 0);
    init_MUTEX(&csyncontrol_devp->sem);    //初始化信号量
     XXXXXX
}
以后在访问csyncontrol_dev中的共享资源时,需要首先获取这个信号量,访问完成后,随即释放掉这个信号量,比如下面的,写操作:

//csycontrol_read函数
static ssize_t csycontrol_read(struct file *filp,char __user *buf, size_t size, loff_t *ppos)
{
        XXXXXX//叉叉的感觉好爽啊,,省去了不少功夫,呵呵
        if(down_interruptible(&dev->sem)) //获取信号量
        {
                return –ERESTARTSYS;
        }
 if (copy_to_user(buf,(void *)(dev->mem + p),count))
 {
  ret = -EFAULT;
 }
 else
 {
  *ppos += count;
  ret = count;
  printk(KERN_INFO "read %d byte(s) from %d",count,p);
 }
 up(&dev->sem);   //释放信号量
        return ret;
}

//csycontrol_write
static ssize_t csycontrol_write(struct file *filp, const char __user *buf,size_t size, loff_t *ppos)
{
 XXXXXX 
        if(down_interruptible(&dev->sem)) //获取信号量
         {
                return –ERESTARTSYS;
        }
        if (copy_from_user(dev->mem + p,buf, count))
  ret = -EFAULT;
 else
 {
  *ppos+= count;
  ret = count;
  printk(KERN_INFO "written %d bytes(s) from %d\n", count, p);
 }
        up(&dev->sem); //释放信号量
 return ret;
}
//csycontrol_ioctl函数
static int csycontrol_ioctl(struct inode *inodep, struct file *filp,unsigned int cmd, unsigned long arg)
{
 struct csycontrol_dev *dev = filp->private_data;
 switch (cmd)
 {
  case MEM_CLEAR://清除全局内存
                        if(down_interruptible(&dev->sem)) //获取信号量
                           {
                           return –ERESTARTSYS;
                        }
                        memset(dev->mem, 0,GLOBALMEM_SIZE);
                        up(&dev->sem); //释放信号量
   printk(KERN_INFO "globalmem is set to zero\n");
   break;
  default:
   return - EINVAL;//其他不支持的命令
 }
 return 0;
}
代码部分也讲完了,说句真的,心里真是不平衡,前边讲了那么多,这里体现的时候它怎么就只有那两行代码呢..

最后,给小王把前面几个专题讲的各种同步机制总结比较一下(各位喜欢的话,也可以打印的哦,反正我是不会追这里要版权问题的,呵呵..)

原创粉丝点击