-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crystal::System::Process#spawn forks, should call posix_spawn() or posix_spawnp() instead #11337
Comments
According to the manpage, So I'm not sure what actual benefit we would get from using |
Here is a related Golang issue with useful insights: golang/go#5838. |
Oooh...! |
I wrote a benchmark, using
lib LibC
fun clone(func : Void* -> LibC::Int, stack : Void*, flags : LibC::Int) : LibC::Int
fun execv(LibC::Char*, LibC::Char**) : LibC::Int
fun dup2(LibC::Int, LibC::Int) : LibC::Int
end
def do_exec(opaque : Void*) : LibC::Int
LibC.dup2(STDOUT.fd, 1)
command = "/bin/echo\0".to_unsafe
args = Array(LibC::Char*).new
args << command
args << "-n\0".to_unsafe
args << "\0".to_unsafe
args << Pointer(LibC::Char).new(0)
error = LibC.execv(command, args.to_unsafe)
return error
end
CLONE_VFORK = 0x00004000
CLONE_VM = 0x00000100
stack_array = Array(LibC::Long).new(1000)
# I am told that everything Linux runs upon except for PowerPC grows the stack downwards.
stack = stack_array.to_unsafe + stack_array.size
big_array1 = Array(UInt8).new(1024 * 1024 * 1024)
# Linux reserves pages when they are allocated, and allocates them when they are written.
big_array1.map! { 0u8 }
big_array2 = big_array1.clone
big_array3 = big_array2.clone
if ARGV.size > 0
version = ARGV[0].to_i
else
version = 0
end
STDERR.puts "Running version #{version}"
case version
when 0
1000.times do
Process.new(command: "/bin/echo", args: ["-n", ""], output: STDOUT)
end
when 1
1000.times do
LibC.clone(->(opaque : Void *){ do_exec(opaque) }, stack, CLONE_VFORK|CLONE_VM)
end
end
|
The change in go that @j8r referred to had some pretty happy users: https://about.gitlab.com/blog/2018/01/23/how-a-fix-in-go-19-sped-up-our-gitaly-service-by-30x/ Aside: Personally I'd prefer to simply not use |
ignore me, probably just some weird overcommit settings issues on a particular clients server. Lots of processes failing all over the place with out-of-memory and upwards of 8GB of memory free |
@stakach Crystal is using |
crystal/src/crystal/system/unix/process.cr
Line 122 in 9f90efe
On Unix lookalikes, the
posix_spawn()
andposix_spawnp()
functions should be available, which would allow this to be implemented withoutfork()
. Obviouslyfork()
is going to break multithread, and even though this implementation hints that it willexec()
, there still seems to be unacceptable overhead for large-memory processes.The text was updated successfully, but these errors were encountered: