The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Блокировка процессов в Linux (linux blocking proccess lock)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: linux, blocking, proccess, lock,  (найти похожие документы)
Date: Fri, 19 Apr 2002 19:18:24 +0000 (UTC) From: Valentin Nechayev <netch@segfault.kiev.ua> Newsgroups: fido7.ru.unix.prog Subject: Блокировка процессов в Linux > Кстати, функцией interruptible_sleep_on() пользоваться не рекомендуют - > в большинстве случаев создается race condition. Т.е. обычная картина - > проверили условие (например, пустоту буфера), вызвали > interruptible_sleep_on() - но между проверкой и переходом в состояние > ожидания может произойти прерывание, которое положит данные в этот > буфер, а процесс этого не заметит и останется ждать следующего. В > <linux/sched.h> есть макрос wait_interruptible(wq, condition), который > позволяет избежать этой ситуации (хитрость в том, что нужно проверять > условие _после_ постановки процесса в очередь). В 2.2.16 он точно есть > (в первых 2.2.x еще не было); в 2.4.x - тем более. Макрос этот называется wait_event[_interruptible]. По крайней мере, в 2.4.18. Но он годится только для крайне простых условий, которые можно проверить атомарно. Для сложных порядок будет куда более заковыристый: lock_subsystem; if( need_wait ) { add_to_waitqueue; set_current_state( TASK_INTERRUPTIBLE ); if(signal_pending(current)) { ... } unlock_subsystem; /* с этого момента могут приходить посторонние воздействия. * если они придут, state изменится на TASK_RUNNING, и schedule() * вернет управление немедленно, без задержки */ schedule(); /* может быть, schedule_timeout() */ lock_subsystem; } unlock_subsystem; Предполагается в качестве обязательного условия, что тот, кто делает wakeup, тоже сделает lock_subsystem, и что schedule() и wake_up*() используют общий лок на очереди шедулера. Я бы все это безобразие с кишками наружу - оформил в виде функции с callback'ами. > Кстати, на http://www.oreilly.com/catalog/linuxdrive2/ дают книжку (на > английском) по написанию драйверов для Linux. /netch
From: Valentin Nechayev <netch@segfault.kiev.ua> SV> при инициализации надо сделать SV> init_waitqueue(&xx_wait); > Hе поверишь, после того как я эту функцию вызвал на sleep_on всё равно > валится Что-то еще не доделал. Сравни код. > Пробовал (видимо имеется ввиду wait_event_interruptible) работает, но > только после того как я в этот макрос поправку внёс, там была такая строка: > current->task = TASK_INTERRUPTIBLE; > Я заменил её на: > current->task = TASK_RUNNING; > иначе он доходил до функции schedule и ждал чего-то (не вис, а ждал) я > посмотрел хелп там написано что schedule не возвратит управление пока > процесс не продолжится выполняться. Ась? TASK_RUNNING тебе должен дать только один эффект (разумеется, если доблестные вояки не переделали это хозяйство) - управление немедленно вернется обратно, или же отдаст управление кому-то более приоритетному. И собственно все. Ты сделал так, что драйвер жрет весь процессор, пока не получит результат. Что ж, это тоже в чем-то метод - очень быстрый и очень грязный хак, если нет 10 минут на нормальный. Но это нехорошо. Ты, по-моему, не учитываешь одного существенного момента. Когда впадаешь в простой sleep, надо четко определить: 1. На каком объекте спать. Объект задается просто адресом в адресном пространстве ядра. Смысл его ровно то, что кто-то по нему сделает wakeup. Если wakeup не сделают и ты не задал таймаут для сна, и не пришел сигнал - то так и будешь спать до скончания века. 2. Кто, когда, почему сделает wakeup. Если никто не делает, или делает на другой адрес - будешь опять же спать до посинения. 3. Сделать, чтобы wakeup вызывался и притом на тот же адрес. В add_wait_queue() первым параметром идет адрес для сна. Вот пример: 11:26:35:netch@vnechayev:/var/tmp/linux-2.2.16>fgrep -w open_wait drivers/char/serial.c | less wake_up_interruptible(&info->open_wait); wake_up_interruptible(&info->open_wait); wake_up_interruptible(&info->open_wait); wake_up_interruptible(&info->open_wait); add_wait_queue(&info->open_wait, &wait); remove_wait_queue(&info->open_wait, &wait); Здесь есть и wakeup на адрес, и подготовка к sleep на нем, и устранение из очереди спящих - через remove_wait_queue(). > После этого изменения всё работало пучком, condition изменяем на 1 и > вылетаем из макроса, как раз то что надо. Не пучком оно.;) Как будет время - переделай на нормальное.

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

Обсуждение [ RSS ]
  • 1, Илья (??), 19:20, 22/02/2016 [ответить]  
  • +/
    Механизм не может работать без смазки.
    Человек не может жить,не владея землёй.
    Дайте механизму хорошую смазку,а человеку-землю и блокировки не понадобятся.
     

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру