0

我无法理解以下两个代码之间的区别。任何人都可以解释以下代码之间的区别并通过示例解释信号量和互斥体之间的区别......

互斥:

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;
}
4

1 回答 1

2

互斥量只不过是一个二进制信号量。这意味着互斥锁只能有两种状态:锁定和解锁。但是信号量可以有两个以上的计数。因此,可以获得信号量锁的进程数等于初始化信号量的计数。

在您的示例中,在第一个代码片段中,无论是读取还是写入,无论是获取锁还是在完成各自的读取或写入后,它本身都会释放锁。由于互斥锁,两者不能同时工作。

而在第二个代码片段中,代码展示了阻塞 I/O 概念,该概念旨在解决 Linux 设备驱动程序(LDD)一书中解释的问题:“当没有数据尚未读取时该怎么办,但我们不在文件结束。默认答案是进入睡眠等待数据”。正如您在代码中看到的,lock 被声明为 Mutex 并且也处于锁定状态。因此,如果在没有数据的情况下进行任何读取,则由于互斥体已处于锁定状态,因此无法获取锁,因此它将进入睡眠状态(简而言之,读取被阻塞)。每当有任何写入出现时,它首先写入设备,然后释放互斥锁。因此,现在阻塞读取可以获取该锁并可以完成其读取过程。在这里,两者不能同时工作,

于 2013-10-04T09:22:46.540 回答