Системный вызов clone () в конечном счете полагается на функциональность форка? - PullRequest
2 голосов
/ 11 ноября 2010

Для класса, который я посещаю, я выполняю некоторую работу непосредственно с системным вызовом clone() в Linux.Мне стало интересно, как это работает на самом деле, и я начал копать.Что меня смущает, так это то, что он, похоже, опирается на те же основы, что и функциональность fork() (они вызывают одну и ту же функцию do_fork(), хотя и с разными аргументами).С одной стороны, это имеет смысл для меня, поскольку поток - это на самом деле простой процесс, но у меня всегда было впечатление, что между созданием потока и способом создания процесса были некоторые существенные различия.Я немного покопался в реализации do_fork(), а затем copy_process() (который do_fork() вызывает), но не смог убедить себя, что понимаю, что происходит.

Итак, для гуру, я что-то упускаю или это действительно так работает?Существуют ли флаги, которые в основном сообщают ОС только о том, сколько копировать, а также о том, с какой инструкции начинать выполнение новой задачи (я думаю, ответ должен быть да , но я просто неточно, как они переводятся)?

Ниже приведен код, на который я смотрю, возможно, вы могли бы объяснить, как аргументы, которые передаются в управление при создании легкого или тяжелого процесса, создаются.

asmlinkage int sys_fork(struct pt_regs *regs){
  #ifdef CONFIG_MMU
      return do_fork(SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
  #else
    /* can not support in nommu mode */
    return(-EINVAL);
  #endif
}


asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
             int __user *parent_tidptr, int tls_val,
             int __user *child_tidptr, struct pt_regs *regs)
{
    if (!newsp)
        newsp = regs->ARM_sp;

    return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
}

Спасибо!

Ответы [ 3 ]

4 голосов
/ 11 ноября 2010

На самом деле, на концептуальном уровне ядро ​​Linux ничего не знает о процессах или потоках, оно знает только о «задачах».

Задача Linux может быть процессом, потоком или чем-то промежуточным. (Между прочим, это означает, что странные дочерние элементы, которые создает vfork (), прекрасно вписываются в парадигму «задач» Linux).

Теперь задачи могут делиться несколькими вещами, см. Все флаги CLONE_ * на странице руководства для clone (2). (Не все эти флаги могут быть описаны как общие, некоторые задают более сложные поведения).

Или новые задачи могут иметь собственные копии соответствующих ресурсов. А начиная с версии 2.6.16, они могут сделать это после запуска, см. Unshare (2).

Например, единственное различие между вызовами vfork () и fork () состоит в том, что для vfork () установлены CLONE_VM и CLONE_VFORK. CLONE_VM заставляет его совместно использовать память своего родителя (так же, как потоки разделяют память), в то время как CLONE_VFORK создает родительский блок до тех пор, пока потомок не освободит свои отображения памяти (вызывая execve () или _exit ()).

Обратите внимание, что Linux - не единственная ОС, которая обобщает процессы и потоки таким образом. План 9 имеет rfork ().

3 голосов
/ 11 ноября 2010

Ничего в на clone manpage не говорит о том, что он "легкий".

Критическое различие заключается в том, что fork создает новое адресное пространство, а clone опционально разделяетадресное пространство между родительским и дочерним элементами, а также файловые дескрипторы и т. д.

Это совместное адресное пространство позднее позволяет использовать упрощенный IPC, но сам процесс не является более тонким.

1 голос
/ 12 ноября 2010

Я понимаю, что разница между всеми тремя клонами, вилками и vfork заключается во флагах, потому что, наконец, все три вызывают do_fork () в ядре

fork () -> C_lib -> sys_fork() -> do_fork ()

vfork () -> C_lib -> sys_vfork () -> do_fork ()

clone () -> C_lib -> sys_clone() -> do_fork ()

Разница между форком и vfork заключается в том, что vfork гарантирует, что потомок будет выполняться первым, а родительский будет блокироваться до тех пор, пока потомок не вызовет exit или exec.vfork передает дополнительный флаг CLONE_VM, этот флаг просит ядро ​​не дублировать таблицу страниц, причина в том, что дочерний процесс будет либо завершать работу, либо выполнять exec, если дочерний процесс ничего не сделает, если дочерний процесс выполняет exec, то таблица страниц определенно будетбыть изменен.Я надеюсь, что флаги форка и vfork теперь ясны на уровне ядра.Теперь давайте рассмотрим флаги клонирования

Основное использование клона - реализовать поток, в котором пространство памяти совместно используется другим, а не стеком.Наряду с тем же параметром, что и для fork и vfork, клон также принимает указатель функции в качестве параметра, который вызывается, как только создается дочерний процесс.

...