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

Смотреть 3d видео

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

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

12.12.09 12:51 dementiy

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. И да, это первый пост.


Теги:

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

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

Посты Комментарии
Последние посты
    Посты Комментарии
    Последние комментарии
      Посты Комментарии
      Изменения
        Посты Комментарии Изменения Черновики Избранное
        Черновики (все)
          Посты Комментарии Изменения Черновики Избранное
          Избранное (всё)
            Посты Комментарии Изменения Черновики Избранное
            Лучшие блоги (все 96)
            Топ пользователей Топ блогов
            Топ пользователей Топ блогов
            Элита (все 2004 из 152 городов)
            Топ пользователей Топ блогов

            Новенькие: Niaque, newstoic, atheist, dieformetal, MrPack
            welinux.ru

            В хорошем качестве hd видео

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


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

            Online video HD

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

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

            Full HD video online

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

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

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