- 论坛徽章:
- 0
|
回复 #6 dreamice 的帖子
我把代码全都贴出来! 先不看,不管write与read这两个是关于信号量,就看open close!程序就这些不知道是哪里出了问题
!把OPEN,CLOSE改成这样:
static int signel_open(struct inode *inode,struct file *file )
{ printk("get lock\n");
spin_lock(&s_lock); 这里取锁,我不放掉!看到close里面能不能把进程给挂起!
f_count++;
return 0;
}
static int signel_close(struct inode *inode,struct file *file)
{ spin_lock(&s_lock); 在这里进程应该挂起才对!!
f_count--;
return 0;
}
运行结果与下面的一样!
#define DEV_NAME "signel"
#define DEV_ID 110
static int flags=0;
static DECLARE_WAIT_QUEUE_HEAD(in);
static int arry[4];
struct semaphore sem;
spinlock_t s_lock; 锁的声明!!!
static int f_count;
static int signel_open(struct inode *inode,struct file *file )
{ printk("get lock\n");
spin_lock(&s_lock);
if(f_count)
{ spin_unlock(&s_lock);
return -EBUSY;
}
f_count++;
spin_unlock(&s_lock);
return 0;
}
static int signel_write(struct file *file,const char __user * buf,size_t count,loff_t *off)
{ printk("%i,%s\n",current->pid,current->comm);
flags=1;
if(down_interruptible(&sem))
{ return -ERESTARTSYS;
}
printk("write data....!!!\n");
if(copy_from_user(&arry,buf,count))
{ up(&sem);
return -EFAULT;
}
wake_up_interruptible(&in);
up(&sem);
return count;
}
static int signel_read(struct file *file,char __user * buf,size_t count,loff_t *off)
{ printk ("%i,%s\n",current->pid,current->comm);
if(wait_event_interruptible(in,flags!=0))
{ return -ERESTARTSYS;
}
if(down_interruptible(&sem))
{ return -ERESTARTSYS;
}
flags=0;
printk("read data....!!!\n");
if(copy_to_user(buf,&arry,count))
{ up(&sem);
return -EFAULT;
}
up(&sem);
return count;
}
static int signel_close(struct inode *inode,struct file *file)
{ f_count--;
return 0;
}
static struct file_operations signel_test = {
.write = signel_write,
.read = signel_read,
.open = signel_open,
.release = signel_close,
};
static int __init init_signel(void)
{ int ret;
sema_init(&sem,1); /* 或者用init_MUTEX(&sem) 初始化并声明为互斥(实际上也就是将信号量为“1”也就是它互斥模式)*/
spin_lock_init(&s_lock); 锁的初始化!!!!!
ret=register_chrdev(DEV_ID,DEV_NAME,&signel_test);
if(ret<0)
{ printk("registre is fail!!\n");
return ret;
}
else
{ printk("registre is scuss!!\n");
devfs_mk_cdev(MKDEV(DEV_ID,0),S_IFCHR | S_IRUSR | S_IWUSR,"signel");
return 0;
}
return 0;
}
static void __exit exit_signel(void)
{ unregister_chrdev(DEV_ID,DEV_NAME);
devfs_remove(DEV_NAME);
}
[ 本帖最后由 shuiyu123 于 2009-3-15 21:42 编辑 ] |
|