There is a significant overhead using fork() over vfork(), specially
when the child process execs a helper. The overhead is in memory space
and time.
# strace -c ./test_fork 1024 200
count=1024, size=204800, total=200M
failed fork=0
time for fork() = 4879.597000 us
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 4.543321 3304 1375 375 clone
0.00 0.000071 0 1033 mmap
0.00 0.000000 0 1 read
0.00 0.000000 0 3 write
0.00 0.000000 0 2 open
0.00 0.000000 0 2 close
0.00 0.000000 0 3 fstat
0.00 0.000000 0 3 mprotect
0.00 0.000000 0 1 munmap
0.00 0.000000 0 3 brk
0.00 0.000000 0 1 1 access
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00 4.543392 2429 376 total
# strace -c ./test_vfork 1024 200
count=1024, size=204800, total=200M
failed fork=0
time for fork() = 82.041000 us
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
96.47 0.001204 1 1000 vfork
3.53 0.000044 0 1033 mmap
0.00 0.000000 0 1 read
0.00 0.000000 0 3 write
0.00 0.000000 0 2 open
0.00 0.000000 0 2 close
0.00 0.000000 0 3 fstat
0.00 0.000000 0 3 mprotect
0.00 0.000000 0 1 munmap
0.00 0.000000 0 3 brk
0.00 0.000000 0 1 1 access
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00 0.001248 2054 1 total
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Michael Adam <obnox@samba.org>
}
}
if (debug_locks != NULL) {
- pid = fork();
+ pid = vfork();
if (pid == 0) {
execl(debug_locks, debug_locks, NULL);
+ _exit(0);
}
+ ctdb_track_child(ctdb, pid);
} else {
DEBUG(DEBUG_WARNING,
(__location__
return;
}
- lock_ctx->child = ctdb_fork(ctdb);
+ lock_ctx->child = vfork();
if (lock_ctx->child == (pid_t)-1) {
DEBUG(DEBUG_ERR, ("Failed to create a child in ctdb_lock_schedule\n"));
}
/* Parent process */
+ ctdb_track_child(ctdb, lock_ctx->child);
close(lock_ctx->fd[1]);
talloc_set_destructor(lock_ctx, ctdb_lock_context_destructor);