Как-то проще вызвать fork
, а затем unshare
, потому что многие аргументы копируются через fork
, которые в противном случае были бы вручную перенесены в clone
. Мой вопрос: в чем разница между (1) вызовом clone
, который разветвляет новый процесс в отдельных пространствах имен, и (2) fork+unshare
, который разветвляет новый процесс, а затем оставляет родительские пространства имен. Предположим, что все флаги пространства имен, переданные в clone
и unshare
, одинаковы.
auto flag = CLONE_NEWUSER | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | SIGCHLD;
Таким образом, с помощью fork ребенку очень легко повторно использовать данные, унаследованные от родителей.
int mydata; // this could be even more complicated, class, struct, etc.
auto pid = fork();
if(pid == 0) {
// reuse inherited data in a copy-on-write manner
unshare(flag);
}
Для клонирования нам иногда приходится переносить данные в другую структуру и передавать их как void*
системному вызову clone
.
int mydata;
clone(func, stack+stack_size, flag, &wrapper_of_data);
Мне кажется, что в приведенном выше примере единственная разница заключается в снижении производительности, где вилка может быть немного дороже. Однако природа fork
избавляет меня от многих усилий, поскольку оба могут создавать процесс в новых пространствах имен.