我无法理解以下两个代码之间的区别。任何机构都可以解释以下代码与之间的区别吗?还用例子解释了信号量和互斥量之间的差异....
相互排斥:
DEFINE_SEMAPHORE(mysem);
static ssize_t dev_read(struct file *file,char *buf, size_t lbuf, loff_t *ppos)
{
int maxbytes, bytes_to_do, nbytes;
maxbytes = SIZE - *ppos;
if(maxbytes < lbuf) bytes_to_do = maxbytes;
else bytes_to_do = lbuf;
if(bytes_to_do == 0){
printk("reached end of device\n");
return -ENOSPC;
}
if(down_interruptible(&mysem))
return -ERESTARTSYS;
nbytes = bytes_to_do - copy_to_user(buf,dev_buf+*ppos,bytes_to_do);
up(&mysem);
*ppos += nbytes;
return nbytes;
}
static ssize_t dev_write(struct file *file,const char *buf, size_t lbuf,
loff_t *ppos)
{
int maxbytes, bytes_to_do, nbytes;
maxbytes = SIZE - *ppos;
if(maxbytes < lbuf) bytes_to_do = maxbytes;
else bytes_to_do = lbuf;
if(bytes_to_do == 0){
printk("reached end of device\n");
return -ENOSPC;
}
if(down_interruptible(&mysem))
return -ERESTARTSYS;
nbytes = bytes_to_do - copy_from_user(dev_buf+*ppos,buf,bytes_to_do);
ssleep(10);
up(&mysem);
*ppos += nbytes;
return nbytes;
}
阻止IO
init_MUTEX_LOCKED(&mysem);
static ssize_t dev_read(struct file *file,char *buf, size_t lbuf, loff_t *ppos)
{
int maxbytes, bytes_to_do, nbytes;
maxbytes = SIZE - *ppos;
if(maxbytes < lbuf) bytes_to_do = maxbytes;
else bytes_to_do = lbuf;
if(bytes_to_do == 0){
printk("reached end of device\n");
return -ENOSPC;
}
if(down_interruptible(&mysem))
return -ERESTARTSYS;
nbytes = bytes_to_do - copy_to_user(buf,dev_buf+*ppos,bytes_to_do);
*ppos += nbytes;
return nbytes;
}
static ssize_t dev_write(struct file *file,const char *buf, size_t lbuf,
loff_t *ppos)
{
int maxbytes, bytes_to_do, nbytes;
maxbytes = SIZE - *ppos;
if(maxbytes < lbuf) bytes_to_do = maxbytes;
else bytes_to_do = lbuf;
if(bytes_to_do == 0){
printk("reached end of device\n");
return -ENOSPC;
}
nbytes = bytes_to_do - copy_from_user(dev_buf+*ppos,buf,bytes_to_do);
ssleep(10);
up(&mysem);
*ppos += nbytes;
return nbytes;
}
答案 0 :(得分:2)
Mutex只不过是一个二进制信号量。这意味着互斥锁只能有两种状态:锁定和解锁。但信号量可以有两个以上的数量。因此,可以获取信号量锁的进程数等于信号量初始化的计数。
在您的示例中,在第一个代码段中,无论是读取还是写入,获取锁定的任何一个本身也会在完成相应的读取或写入后释放锁定。由于互斥锁,两者都无法同时工作。
在第二个代码片段中,代码展示了阻塞I / O概念,旨在解决Linux设备驱动程序(LDD)一书中解释的问题:“当没有数据尚未读取时该怎么办,但我们”不是在文件结束。默认答案是进入睡眠等待数据“。正如您在代码中看到的那样,lock被声明为Mutex并且也处于锁定状态。因此,如果在没有数据时进行任何读取,则由于互斥锁已处于锁定状态,因此无法获取锁定,因此它将进入休眠状态(简短读取被阻止)。无论何时写入,它首先写入设备然后释放互斥锁。因此,现在阻塞读取可以获取该锁定并可以完成其读取过程。在这里,两者都不能同时工作,但是锁定获取和释放机制是以这样的方式同步的,即在写入不向设备写入任何内容之前读取不能进行。