Разница между взаимным исключением и блокировкой ввода-вывода в программировании ядра?

Я не могу понять разницу между двумя следующими кодами. Может ли кто-нибудь объяснить разницу между следующими кодами, а также объяснить разницу между семафором и мьютексом на примере....

Взаимное исключение:

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

Заблокированный ввод-вывод

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

person Sandy    schedule 04.10.2013    source источник
comment
Разница в том, что второй код содержит ужасные ошибки и не компилируется. Откуда это взялось?   -  person CL.    schedule 04.10.2013
comment
использовать семафор статической структуры mysem = __SEMAPHORE_INITIALIZER(mysem,0) вместо init_MUTEX_LOCKED(&mysem)   -  person Sandy    schedule 04.10.2013


Ответы (1)


Мьютекс — это не что иное, как бинарный семафор. Это означает, что мьютекс может иметь только два состояния: заблокирован и разблокирован. Но семафор может иметь более двух счетов. Таким образом, количество процессов, которые могут получить блокировку семафора, равно количеству, с которым семафор инициализируется.

В вашем примере в первом фрагменте кода, независимо от того, читается он или пишется, тот, кто получает блокировку, сам освобождает блокировку также после завершения соответствующего чтения или записи. Оба не могут работать одновременно из-за мьютекса.

В то время как во втором фрагменте кода код демонстрирует концепцию блокировки ввода-вывода, которая предназначена для решения проблемы, описанной в книге «Драйверы устройств Linux (LDD)»: «что делать, когда нет данных для чтения, но мы еще не на конец файла. Ответ по умолчанию — перейти в спящий режим в ожидании данных». Как вы можете видеть в коде, блокировка объявлена ​​как Mutex и также находится в заблокированном состоянии. Таким образом, если какое-либо чтение происходит при отсутствии данных, оно не может получить блокировку, поскольку мьютекс уже находится в заблокированном состоянии, поэтому он переходит в спящий режим (короче говоря, чтение заблокировано). Всякий раз, когда приходит какая-либо запись, она сначала записывает в устройство, а затем освобождает мьютекс. Итак, теперь заблокированное чтение может получить эту блокировку и завершить процесс чтения. Здесь также оба не могут работать одновременно, но механизм получения и снятия блокировки синхронизирован таким образом, что чтение не может выполняться до тех пор, пока запись ничего не запишет на устройство.

person pratik    schedule 04.10.2013