Видео ролики бесплатно онлайн

Смотреть мама и сын видео

Официальный сайт 70rus 24/7/365

Смотреть видео бесплатно

dementiy 12.12.2009 12:51

CodingМеханизм создания процессов в Linux

Создать процесс в системе можно несколькими способами, здесь я опишу как происходит создание процесса начиная с функции fork():
1
2
3
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);


fork() создает дочерний процесс, который является практически точной копией родительского процесса. Одним из различий являются значения PID и PPID.
fork() при успешном вызове возвращает два значения, одно в родительский — PID созданного потомка, а второе в дочерний — 0. Если же вызов оказался неудачным, то родителю возвращается -1, потомок не создается, а в errno устанавливается код ошибки.
Возвращаемое значение имеет тип pid_t, хотя на самом деле это обычное целое (int). Это можно проследить в коде ядра:

1
2
3
4
#define pid_t __pid_t             (<sys/types.h>)
#define __pid_t __PID_T_TYPE (<bits/types.h>)
#define __PID_T_TYPE __S32_TYPE (<bits/typesizes.h>)
#define __S32_TYPE int (<bits/types.h>)


Приведем простой пример использования функции fork():

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/* fork_ex.c --- простой пример использования fork() */
#include <stdio.h> /* printf */
#include <sys/wait.h> /* waitpid */
#include <errno.h> /* perror */
#include <sys/types.h> /* fork */
#include <unistd.h> /* fork */

int main(void) {
pid_t pid;
int status;

switch(pid = fork()) {
case -1:
perror("fork");
return -1;
case 0:
printf("Выполняется дочерний процесс\n");
exit(4);
}

printf("Выполняется родительский процесс\n");
printf("Идентификатор дочернего процесса - %d\n", pid);
if ((pid = waitpid(pid, &status;, 0)) && WIFEXITED(status)) {
printf("Дочерний процесс с PID = %d \
завершил выполнение", pid);
printf("Код статуса завершения \
равен %d", WEXITSTATUS(status));
}
return 0;
}


Функция fork(), в свою очередь, вызывает системный вызов sys_clone(). В этом можно убедиться, если выполнить трассировку программы с помощью команды strace или ltrace:

1
2
3
4
5
6
7
8
9
$ strace ./fork_ex
...
clone(Выполняется дочерний процесс child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7eab708) = 9500
...

$ ltrace -S ./fork_ex
...
SYS_clone(0x1200011, 0, 0, 0, 0xb7eab708 Выполняется дочерний процесс ) = 9500
...


Системный вызов sys_clone (определен в файле arch/x86/kernel/process_XX.c), о котором можно прочитать на страницах справочного руководства man, является архитектурно-зависимым, вот его прототип (прототипы приводятся только для архитектуры x86):

1
2
3
4
5
6
7
8
/*** arch/x86/kernel/process_32.c ***/
int sys_clone(struct pt_regs *regs)

/*** arch/x86/kernel/process_64.c ***/
asmlinkage longa
sys_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tid, void __user *child_tid,
struct pt_regs *regs)


В любом случае sys_clone ссылается на архитектурно-независимую функцию do_fork():

1
2
3
...
return do_fork(clone_flags, newsp, regs, 0, parent_tidptr,child_tidptr);
...


Функция do_fork(), как уже было сказано, является архитектурно-независимой функцией и несет ответственность за процесс дублирования. Она определена в файле kernel/fork.c, вот ее прототип:

1
2
3
4
5
6
long do_fork(unsigned long clone_flags, 
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr)


do_fork() в свою очередь вызывает функцию copy_process(), которая выполняет фактическую работу по созданию нового процесса и повторному использованию данных родительского процесса. Ее вызов происходит следующим образом:

1
2
3
4
...
p = copy_process(clone_flags, stack_start, regs, stack_size,
child_tidptr, NULL, trace);
...


В итоге выстраивается следующая схема:

vfork() ->
fork () -> sys_clone() -> do_fork() -> copy_process()
clone() ->

Хочу сказать, что статью считать "от и до" своей я не могу, это своего рода "компиляция" различных статей с моими доработками.

P.S. Вот выложил pdf (и тут) с этим же текстом, плюс в нем приводится полный код функций do_fork() и copy_process() с небольшими комментариями.
P.P.S. И да, это первый пост.


Тэги: kernel processes
+ 17 -
Похожие Поделиться

m0nhawk 12.12.2009 13:03 #
+ 0 -
За статью +.
Сам пользовался форком но лень было разбираться как он работает, у тут коротко и понятно.

А вот .pdf лучше публиковать на http://www.scribd.com/. Можно будет и прочитать, не качая, и скачать если понадобится.
m0nhawk 12.12.2009 13:04 #
+ 1 -
Извините, неправильно ссылку дал Scribd.
dementiy 12.12.2009 13:40 #
+ 1 -
Спасибо за ресурс, ссылку добавил.
m0nhawk 12.12.2009 14:39 #
+ 0 -
А с помощью чего .pdf делали?
dementiy 12.12.2009 14:59 #
+ 3 -
С помощью OpenOffice, я там всегда тексты набираю, а затем экспортирую в pdf.
exelens 12.12.2009 14:46 #
+ 0 -
Фиксед
|xed| 12.12.2009 15:52 #
+ 2 -
пришлось залогинится чтобы вам + поставить +) так держать...
Denis 12.12.2009 16:14 #
+ 0 -
Да-да, я тоже преодолел свою лень именно для этого. Очень интересная статья.
exelens 12.12.2009 16:17 #
+ 0 -
В какой блог перенести данную статью? Или создать новый?
dementiy 12.12.2009 16:38 #
+ 0 -
Мое мнение пока оставить так, как есть (пусть будет Coding). А если будут появляться новые статьи, то тогда уже и подумать о новом блоге.
xT 12.12.2009 16:41 #
+ 0 -
я оказался быстрее)))
commonD 13.12.2009 00:43 #
+ 0 -
Вот это действительно отличная работа! Еще хотелось бы услышать про механизмы работы с памятью при вызовах fork, exec.

Смотреть онлайн бесплатно

Онлайн видео бесплатно


Смотреть русское с разговорами видео

Online video HD

Видео скачать на телефон

Русские фильмы бесплатно

Full HD video online

Смотреть видео онлайн

Смотреть HD видео бесплатно

School смотреть онлайн