2012-06-25 1 views
3

Давайте рассмотрим сценарий с одним процессором.Почему реализация очереди ожидания ожидает цикла, пока не будет выполнено условие?

wait_event_interruptible() (или другие API ожидания) ждут в цикле до тех пор, пока не будет выполнено определенное условие.

Теперь, поскольку linux имеет потоки, реализованные как отдельные процессы, я считаю, что ложный сигнал (где wait_event* разбужен с условием, не выполненным) указывает на ошибку в программе/драйвере.

Я не прав? - Существует ли какой-либо правильный сценарий, когда такие ложные следы могут случиться и использоваться? Другими словами, зачем ждать состояния в цикле в wait_event* реализации?

ответ

7

Обычный прецедент для очередей ожидания с прерываниями. Возможно, ваш драйвер ядра в настоящее время ждет на трех разных условиях, каждый из которых будет разбужен прерыванием.

Это позволяет обработчику прерываний ядра просто пробудить всех слушателей, которые затем могут определить между собой, если их конкретное состояние произошло, или если они должны проснуться.

Кроме того, вы можете получить ложные прерывания, так как прерывания могут быть разделены и из-за прерываний, отложенных и объединенных.


Добавление некоторого кода и того, что не пытаться быть более явным.

Я написал код ниже, который может быть частью драйвера ядра. Обработчик прерываний просто пробуждает всех слушателей. Однако на самом деле не все слушатели могут быть сделаны. Оба будут разбужены одним и тем же прерыванием, но оба они будут смотреть, чтобы убедиться, что их конкретное условие сделано до продолжения.

// Registered interrupt handler 
static irqreturn_t interrupt_handler(void *private) { 
    struct device_handle *handle = private; 
    wake_up_all(&handle->wait); 
} 

// Some Kernel Thread 
void program_a(struct device_handle * handle) { 
    wait_event_interruptible(&handle->wait, hardware_register & 0x1); 
    printk("program_a finished\n"); 
} 

// Some other kernel thread 
void program_b(struct device_handle * handle) { 
    wait_event_interruptible(&handle->wait, hardware_register & 0x2); 
    printk("program_b finished\n"); 
} 
+0

Может ли драйвер ждать на нескольких условиях?Разве не так, как только процесс приостанавливается из-за первого ожидания, ничего другого не может выполнить? Поэтому я предполагаю, что может быть самое близкое подождать? – Chethan

+0

Я добавил код. Но модуль ядра может иметь несколько потоков, выполняющихся на нем в любой момент времени. –

0

Даже в сценарии с одним процессором ядро ​​является упреждающим, то есть элемент управления может в любой момент перейти к другому потоку/процессу, поэтому поведение будет таким же, как и многопроцессорным. Хорошая дискуссия по проблеме выплавляемым ожидания здесь: http://www.linuxjournal.com/node/8144/print

+0

Согласен, что управление может проходить. Но я не вижу, как цикл в 'wait_event' решает проблему синхронизации, описанную в статье. Кажется, что петли являются попыткой повторить попытку. Я просто хочу знать, почему – Chethan

3

Код:

#define __wait_event(wq, condition)      \ 
do {         \ 
    DEFINE_WAIT(__wait);      \ 
            \ 
    for (;;) {       \ 
     prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); \ 
     if (condition)      \ 
      break;      \ 
     schedule();      \ 
    }        \ 
    finish_wait(&wq, &__wait);     \ 
} while (0) 

(Кроме того, что ядро ​​является упреждающим ...)

Я предполагаю, что вы имеете в виду к бесконечной петле «за» выше? Если это так, основная причина заключается в следующем:

Код не делает никаких предположений о состоянии после его пробуждения. Просто проснувшись, не означает, что событие, которое вы ждали, действительно произошло; вы должен перепроверять. Именно это достигается циклом. Если условие «если» выполняется (что должно быть в нормальном случае), он выходит из цикла, иначе (ложное пробуждение) он снова начинает спать, вызывая расписание().

 Смежные вопросы

  • Нет связанных вопросов^_^