Мьютексы ядра Linux - PullRequest
       8

Мьютексы ядра Linux

6 голосов
/ 21 января 2011

Я читаю «Драйверы устройств Linux 3-е издание», главу о параллелизме и условиях гонки. Есть пример, который я не совсем понимаю; они говорят об общем паттерне в программировании ядра, когда нужно инициировать действие (например, новый поток ядра или пользовательский процесс, запрос существующего процесса или аппаратное действие) вне текущего потока, дождаться, пока это действие полный. Пример не очень эффективного решения:

struct semaphore sem;
init_MUTEX_LOCKED(&sem);
start_external_task(&sem);
down(&sem);

Затем они предлагают вызвать внешнюю задачу (& sem), когда ее работа завершена.

Я не понимаю, почему мы не можем сделать это так:

struct semaphore sem;
down(&sem);
start_external_task(&sem);

Почему необходимо создать мьютекс в заблокированном состоянии, а затем получить мьютекс после запуска задачи?

С нетерпением жду ответа от вас! Спасибо.

Ответы [ 3 ]

10 голосов
/ 21 января 2011

Когда вы вызываете down (), ваш поток блокируется, пока другой поток не подаст сигнал семафору. Поскольку другой поток еще не запущен, он будет блокироваться на неопределенный срок. Вот почему вам нужно сначала запустить поток, а затем вызвать down () для блокировки до завершения потока.

Если поток завершает работу до того, как вы вызовете down (), это нормально, потому что семафор будет сигнализирован, а down () просто очистит сигнал и возвратит.

3 голосов
/ 21 января 2011

В первом примере down (& sem) будет ожидать вызова external_task (& sem) и эффективно приостанавливать основной поток до завершения задачи.В вашем коде down () заблокирует основной поток навсегда, так как пока нет задачи вызвать up ()

1 голос
/ 21 января 2011

Вызов:

init_MUTEX_LOCKED(&sem);

Создает новый семафор в «режиме мьютекса», инициализированный равным 0. Это означает, что вызов down() будет блокироваться.Соответствующий вызов:

init_MUTEX(&sem);

Создает семафор, инициализированный в 1.

В первом примере вы инициализируете семафор 0, вы создаете свою external_task и вызываете блокировку down() доваша задача вызывает up().

Во втором примере вы не инициализируете свой семафор, вызываете down(), блокирующее выполнение, и не выполняете external_task, который может вызвать up(), чтобы разблокировать вас.Таким образом, никогда не достигается вызов create external_task.

Кстати, процесс инициализации семафора с помощью init_MUTEX_LOCKED был удален в версии ядра 2.6.37.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...