Как ядрото проследява кои процеси получават данни от прекъсване?

В превантивно ядро ​​(да речем Linux), да кажем, че процес A прави повикване до getc на stdin, така че е блокиран в очакване на символ. Чувствам, че имам основно неразбиране как ядрото знае тогава да събуди процес A в този момент и да достави данните, след като бъдат получени.

Моето разбиране е, че тогава този процес може да бъде поставен в спряно състояние, докато планировчикът планира други процеси/нишки да се изпълняват, или той се изпреварва. Когато се случи натискане на клавиш, чрез запитване/прекъсвания в зависимост от изпълнението, операционната система стартира драйвер на устройство, който декодира клавиша, който е бил натиснат. Въпреки това е възможно (и вероятно) моят процес A да не се изпълнява в момента. В този момент съм объркан как моят процес, който беше блокиран в очакване на I/O, сега е поставен на опашка, за да стартира отново, особено как знае кой процес чака какво. Изглежда, че драйверите на устройството държат някаква форма на опашка за изчакване.

По същия начин и не съм сигурен дали това е точно свързано с горното, но ако прозорецът на браузъра ми например е на фокус, изглежда, че получава натискания на клавиши, но не и други прозорци. Всеки прозорец/процес има ли способността да "слуша" за събития от клавиатурата, дори ако не са на фокус, но просто не го правете заради потребителското изживяване?

Така че съм любопитен как ядрата (или как някои) следят кои процеси чакат за кои събития и когато тези събития постъпят, как определя кои процеси да планират за изпълнение?


person rb612    schedule 31.05.2020    source източник


Отговори (1)


Събитията, които процесите изчакват, са абстрактни софтуерни събития, като например определена опашка не е празна, а не конкретни хардуерни събития, като възникване на прекъсване 4635.

Някои конфигурации (може би ръководени от хардуерно описание като дърво на устройството) идентифицират прекъсване 4635 като сигнал от дадено серийно устройство с даден адрес. Драйверът на серийното устройство се конфигурира, така че да има достъп до регистрите на устройството на този сериен порт и прикрепя своя манипулатор на прекъсване към дадения идентификатор на прекъсване (4635).

Веднъж конфигуриран, когато се повдигне прекъсване от серийното устройство, най-ниското ниво на ядрото извиква манипулатора на прекъсванията на това серийно устройство. На свой ред, когато манипулаторът види пристигащ нов символ, той го поставя във входната опашка на това устройство. Докато поставя знака в опашка, може да забележи, че някои процеси чакат тази опашка да не е празна и да ги накара да бъдат изпълнени.

Това приблизително описва ситуацията с използване на променливи на условието като механизъм за сигнализиране между прекъсвания и процеси, както беше установено в UNIX-y ядрата преди 44 години. Други подходи включват освобождаване на семафор за всеки знак в опашката; или отговаряне със съобщения за всеки знак. Има много форми на синхронизация, които могат да се използват.

Общото за всички подобни механизми е, че повикващият избира да спре себе си, за да изчака io да завърши; и го прави, като свързва спирането си с екземпляра на обекта, от който очаква вход.

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

Така че операционната система не насочва изрично знака от устройството към приложението; серия от имплицитни и непреки стъпки прави.

person mevets    schedule 31.05.2020
comment
Благодаря ти! Това е полезно. Така че това означава ли, че само един процес може да използва даден символ, или това взаимно изключване е нещо, което зависи от изпълнението (т.е. драйвер може да достави един и същ символ на множество чакащи процеси?) - person rb612; 01.06.2020
comment
Има много стратегии за това, отново реализирани чрез слоеве абстракции в различни операционни системи. Кулминацията на сесиите и контрола на задачите в производните на UNIX операционни системи отговаря на това по начин, който отнема само месеци усилия, за да се разбере :) - person mevets; 01.06.2020
comment
Накратко, шофьорът го доставя на опашка. Мениджърът на опашката решава коя „сесия“ трябва да я получи и процесът, принадлежащ към тази сесия, я получава. И така, още един слой абстракция. Ако си играете с процес, който задава своя stdin в необработен режим, fork()s, тогава и родителят, и детето четат(2) от 0 и printf(%d: got %c\n, getpid(), c) ; можете да видите как работи от първа ръка. - person mevets; 01.06.2020