Амит Саха, превод Въведение в процесите в Linux
И така, какво е "процес"?
Дескриптори на процеси
Ядрото на Linux използва кръгов двойно свързан списък от записи struct task_struct за съхраняване на манипулатори на процеса. Тази структура е декларирана вlinux/sched.h. По-долу са няколко полета от тази структура от ядрото 2.6.15-1.2054_FC5, започващи от ред 701:
Първият ред на структурата определя полето на състоянието като volatile long. Тази променлива се използва за проследяване на състоянието на изпълнение на процес, което е една от следните стойности:
Ключовата думаvolatile тук не означава нищо - вижте http://www.kcomputing.com/volatile.html за повече подробности.
Свързани списъци
Преди да преминем към разглеждане на това как задачите/процесите (ще използваме двата термина взаимозаменяемо) се съхраняват в ядрото, трябва да разберем как се използват кръгови свързани списъци в ядрото. Следната реализация е стандартната реализация и се използва във всички източници на ядрото. Свързаните списъци са декларирани вlinux/list.hи тяхната структура е много проста:
Същият файл дефинира още няколко макроса и функции, които можете да използвате за манипулиране на свързани списъци. Това стандартизира използването на свързани списъци, което спестява на хората необходимостта да „преоткриват колелото“ и да въвеждат нови грешки в своя код.
Ето някои връзки към източници, свързани със свързани списъци на ядрото:
- Отлично есе беше дадено в неговия блог от Суман Адак.
- Източници на ядрото на Linux: ,
- „Разработка на ядрото на Linux“, от Робърт Лав (Приложение A)
- http://www.win.tue.nl/
Списък със задачи на ядрото
Сега нека да видим как ядротоLinux използва двойно свързани списъци за съхраняване на записи на процеси. Търсенето на struct list_head в дефиницията на struct task_struct ни дава следния ред:
Както знаете, "бащата на всички процеси" в системата Linux е процесътinit. Така че трябва да е в началото на списъка, въпреки че, строго погледнато, няма начало, тъй като говорим за цикличен списък. Манипулаторът на процесаinitе статично разпределен:
Следващата фигура илюстрира свързан списък на процесите в паметта:
Има няколко макроса и функции, които ни помагат да се движим в този списък:
for_each_process() е макрос, който преминава през целия списък от задачи. Той е дефиниран в linux/sched.h, както следва:
next_task() е макрос, дефиниран в linux/sched.h, който връща следващата задача от списъка:
Макросът list_entry() е дефиниран в linux/list.h:
Макросът container_of() се дефинира по следния начин:
И накрая, current дереферира полето за задача на структурата thread_info, което е показано по-долу от asm/thread_info.h, с current_thread_info()->task;
thread_info структура и си помислих, че тъй като нишката е единица за изпращане, така че текущата информация за процеса очевидно ще бъде получена от текущо изпълняваната нишка.
Използвайки макроса current и init_task, можем да напишем модул на ядрото, който ще проследи веригата от текущия процес доinit.
Е, току-що започнахме да се запознаваме с една от фундаменталните абстракции в системата Linux - концепцията за процес. Може би в бъдеще ще има продължение на тези бележки, в които ще разгледаме други важни концепции.
До скоро, Приятно хакване!
Други ресурси:
- Ядрото на LinuxРъководство за програмиране на модули за 2.6.x ядра
- Makefile, използван за компилиране на модули на ядрото: