Линукс. Блокиране на процесите
| Информационни технологии | 2009-12-04 | 65 сваляния |
Блокиране на процесите

Какво бихте направили, ако някой ви помоли да свършите нещо, а вие нямате възможност точно в този момент? Ако сте човешко същество, и ви притеснява някой друг човек, единственият начин е да кажете: "Не мога сега, зает съм! Разкарай се!" Но ако сте модул на ядрото и ви притеснява някой процес, имате още една възможност - да "приспите" процеса до момента, в който можете да го обслужите. В края на краищата кернелът постоянно слага разни процеси да спят и ги буди (по този начин изглежда, като че ли множество процеси работят по едно и също време на един и същ процесор).
Този модул на кернела е пример за това. Файлът (наречен /proc/sleep) може да бъде отворен само от един процес едновременно. Ако файлът е вече отворен, модулът на кернела извиква module_interuptible_sleep_on. Тази функция променя състоянието на задачата (задачата, или task, представлява структура от данни на кернела, която съдържа информация за един процес и за системното обръщение в което е той, ако въобще има такова) към TASK_INTERRUPTIBLE, което означава, че задачата няма да тръгне отново, докато не бъде "събудена" по някакъв начин, и я допълва към WaitQ, опашката от задачи, чакащи достъп до файла. Тогава функцията се обръща към разписанието за контекстно превключване към различен процес - такъв, от който има някаква полза за CPU-то.
Когато процесът е свършил работата си с файла, той го затваря, и се обръща към module_close. Тази функция събужда всички процеси в опашката (понеже няма механизъм за събуждане на само един от тях). След това се връща и процесът, който току-що е затворил файла, може да продължи да работи. По някое време определящият разписанието решава, че на този процес му стига толкова, и предава контрола над CPU-то на друг процес. Впоследствие на един от процесите, който е бил на опашката, му се дава контрол над процесора от разписанието. Той се стартира точно от мястото веднага след обръщението към module_interruptible_sleep_on. След това може да продължи, за да установи една глобална променлива, която да съобщи на всички други процеси, че този файл все още е отворен, и продължава да "живее". Когато другите процеси получат малко процесорно време, те поглеждат тази глобална променлива и се връщат да спят.
За да стане животът още по-интересен, module_close няма монопол над събуждането на процесите, които чакат за достъп до файла. Един сигнал, като например Ctrl+C (SIGINT) може също да събуди процес. В този случай ние искаме незабавно да се върнем с EINTR. Това е важно, за да могат потребителите например да убият процеса преди той да получи файла.
Има още едно нещо, което трябва да се запомни.Понякога процесите не искат да спят - те или искат да получат това, което им трябва, и то незабавно, или да им бъде казано, че това не може да стане. Когато отварят файла, тези процеси използват флага O_NONBLOCK. Предполага се в такъв случай кернелът да отговори с връщане на код за грешка -EAGAIN от операциите, които иначе би блокирал, като например отварянето на файла в този случай.
ex sleep.c
/* sleep.c - create a /proc file, and if several
* processes try to open it at the same time, put all
* but one to sleep */
/* Copyright (C) 1998-99 by Ori Pomerantz */
/* The necessary header files */
/* Standard in kernel modules */
#include /* We're doing kernel work*/
#include /* Specifically, a module*/
/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include
#endif
/* Necessary because we use proc fs */
#include
/* For putting processes to sleep and waking them up*/
#include
#include
Тагове от реферата: окиране, инукс, процесит, правил











