페이지 테이블을 복사해야 하기 때문에 상위 프로세스가 더 많은 메모리를 사용하므로 fork(2)
호출 속도가 느려집니다. 자식 프로세스( Kernel#system
, IO::popen
, Process::spawn
등)를 생성하는 exec 함수 계열 중 하나가 뒤따르는 fork()의 여러 일반적인 사용에서 이 오버헤드를 제거하는 것이 가능합니다. 특별한 프로세스 생성 인터페이스( posix_spawn()
, vfork()
등)를 사용하여
posix-spawn 라이브러리는 사용 가능한 경우 빠른 프로세스 생성 인터페이스를 활용하고 그렇지 않은 시스템에서 정상적인 폴백을 제공하는 방식으로 Ruby 1.9 Process::spawn
인터페이스의 하위 집합을 구현하는 것을 목표로 합니다.
Process::spawn
인터페이스와 Ruby >= 1.8.7(현재 MRI에만 해당)에서 Kernel#system
, Kernel#`
등의 향상된 버전의 대규모 호환 하위 집합입니다.POSIX::Spawn::Child
클래스입니다. 다음 벤치마크는 Linux 2.6 및 MacOS X에서 상주 메모리 크기가 증가할 때 하위 프로세스를 포크/실행하는 데 필요한 시간을 보여줍니다. 테스트는 패키지에 포함된 posix-spawn-benchmark
프로그램을 사용하여 실행되었습니다.
posix_spawn
은 fork+exec
보다 빠르며 POSIX_SPAWN_USEVFORK
와 함께 사용하면 일정한 시간에 실행됩니다.
대규모 상위 프로세스의 경우 fork+exec
매우 느립니다.
posix_spawn
은 fork+exec
보다 빠르지만 둘 다 상위 프로세스의 크기에 영향을 받지 않습니다.
이 라이브러리에는 두 가지 별도의 인터페이스가 포함되어 있습니다. 새로운 Ruby 1.9 Process::spawn
메소드를 기반으로 하는 하위 레벨 프로세스 생성 인터페이스인 POSIX:: POSIX::Spawn::spawn
::spawn 과 쉬운 생성을 위한 상위 레벨 클래스인 POSIX::Spawn::Child
. 간단한 문자열 기반 표준 입력/출력/오류 스트림 처리를 사용하는 프로세스입니다. 전자는 훨씬 더 다재다능하고, 후자는 특정 일반적인 시나리오에 훨씬 적은 코드를 필요로 합니다.
POSIX::Spawn
모듈(동반된 C 확장의 도움을 받아)은 주로 IEEE Std 1003.1 posix_spawn(2)
시스템 인터페이스를 사용하여 Ruby 1.9 Process::spawn 인터페이스의 하위 집합을 구현합니다. 이는 다양한 UNIX 운영 체제에서 널리 지원됩니다.
가장 간단한 형태로 POSIX::Spawn::spawn
메소드를 사용하여 Kernel#system
과 유사한 하위 프로세스를 실행할 수 있습니다.
require 'posix/spawn'
pid = POSIX::Spawn::spawn('echo', 'hello world')
stat = Process::waitpid(pid)
첫 번째 줄은 단일 인수로 echo
실행하고 즉시 새 프로세스의 pid
반환합니다. 두 번째 줄은 프로세스가 완료될 때까지 기다리고 Process::Status
개체를 반환합니다. spawn
system
처럼 프로세스가 실행을 완료할 때까지 기다리지 않고 자식의 종료 상태를 가져오지 않는다는 점에 유의하세요. Process::waitpid
(또는 이에 상응하는 항목)를 호출해야 합니다. 그렇지 않으면 프로세스가 좀비가 됩니다.
spawn
메소드는 새 프로세스의 환경 설정부터 하위 작업 디렉터리 변경, 임의 파일 설명자 리디렉션에 이르기까지 수많은 추가 작업을 수행할 수 있습니다.
자세한 내용은 Ruby 1.9 Process::spawn
문서를 참조하고 POSIX::Spawn::spawn
에서 지원하는 다양한 Process::spawn
기능에 대한 전체 설명은 아래 STATUS
섹션을 참조하세요.
system
, popen4
및 `
spawn
메서드 외에도 Kernel#system
및 Kernel#`
의 Ruby 1.9 호환 구현이 POSIX::Spawn
모듈에 제공됩니다. popen4
메소드는 리디렉션된 stdin, stdout 및 stderr 객체를 사용하여 프로세스를 생성하는 데 사용할 수 있습니다.
POSIX::Spawn
모듈은 클래스와 모듈에 혼합되어 해당 네임스페이스에 spawn
및 모든 유틸리티 메서드를 포함할 수도 있습니다.
require 'posix/spawn'
class YourGreatClass
include POSIX::Spawn
def speak(message)
pid = spawn('echo', message)
Process::waitpid(pid)
end
def calculate(expression)
pid, in, out, err = popen4('bc')
in.write(expression)
in.close
out.read
ensure
[in, out, err].each { |io| io.close if !io.closed? }
Process::waitpid(pid)
end
end
POSIX::Spawn::Child
클래스에는 하위 프로세스를 실행하고 표준 입력, 출력 및 오류 스트림에서 읽기/쓰기를 위한 논리가 포함되어 있습니다. 모든 입력을 단일 문자열로 받아들이고 모든 출력을 단일 문자열로 제공하도록 설계되었으므로 명령 안팎으로 대량의 데이터를 스트리밍하는 데 적합하지 않습니다. 즉, 몇 가지 이점이 있습니다.
select(2)
사용) - 하나 이상의 스트림에서 PIPE_BUF
제한을 초과하여 모든 파이프 중단 사례를 처리합니다. POSIX::Spawn::Child
인스턴스화될 때 표준 spawn
인수를 사용하고 모든 입력을 쓰고 모든 출력을 읽은 후 완료될 때까지 프로세스를 실행합니다.
>> require 'posix/spawn'
>> child = POSIX::Spawn::Child.new('git', '--help')
stdout / stderr에 기록된 프로세스 출력을 검색하거나 프로세스의 종료 상태를 검사합니다.
>> child.out
=> "usage: git [--version] [--exec-path[=GIT_EXEC_PATH]]n ..."
>> child.err
=> ""
>> child.status
=> #<Process::Status: pid=80718,exited(0)>
생성 직후 새 프로세스의 stdin에 데이터를 쓰려면 :input
옵션을 사용하십시오.
>> child = POSIX::Spawn::Child.new('bc', :input => '40 + 2')
>> child.out
"42n"
추가 옵션을 사용하여 하위 프로세스가 중단되기 전 최대 출력 크기( :max
) 및 실행 시간( :timeout
)을 지정할 수 있습니다. 자세한 내용은 POSIX::Spawn::Child
문서를 참조하세요.
POSIX::Spawn::Child.new
인스턴스화되는 즉시 프로세스를 생성합니다. 결과적으로 예외(최대 출력 크기 도달, 시간 제한 또는 기타 요인에 도달)로 인해 중단된 경우 생성자가 완료되지 않았기 때문에 out
또는 err
결과에 액세스할 수 없습니다.
프로세스가 중단되었을 때 사용할 수 있는 out
데이터 err
가져오려면 POSIX::Spawn::Child.build
대체 형식을 사용하여 프로세스를 즉시 생성하지 않고 하위 항목을 만듭니다. exec!
예외를 포착할 수 있는 위치에서 명령을 실행하려면 다음을 수행하십시오.
>> child = POSIX::Spawn::Child.build('git', 'log', :max => 100)
>> begin
?> child.exec!
?> rescue POSIX::Spawn::MaximumOutputExceeded
?> # limit was reached
?> end
>> child.out
"commit fa54abe139fd045bf6dc1cc259c0f4c06a9285bbn..."
MaximumOutputExceeded
예외가 발생하면 내부 버퍼링으로 인해 실제 결합된 out
및 err
데이터가 :max
값보다 약간 길어질 수 있습니다.
POSIX::Spawn::spawn
메소드는 Ruby 1.9의 Process::spawn
과 최대한 호환되도록 설계되었습니다. 현재는 호환 가능한 하위 집합입니다.
이러한 Process::spawn
인수는 현재 Spawn::spawn
, Spawn::system
, Spawn::popen4
및 Spawn::Child.new
에서 지원됩니다.
env: hash
name => val : set the environment variable
name => nil : unset the environment variable
command...:
commandline : command line string which is passed to a shell
cmdname, arg1, ... : command name and one or more arguments (no shell)
[cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)
options: hash
clearing environment variables:
:unsetenv_others => true : clear environment variables except specified by env
:unsetenv_others => false : don't clear (default)
current directory:
:chdir => str : Not thread-safe when using posix_spawn (see below)
process group:
:pgroup => true or 0 : make a new process group
:pgroup => pgid : join to specified process group
:pgroup => nil : don't change the process group (default)
redirection:
key:
FD : single file descriptor in child process
[FD, FD, ...] : multiple file descriptor in child process
value:
FD : redirect to the file descriptor in parent process
:close : close the file descriptor in child process
string : redirect to file with open(string, "r" or "w")
[string] : redirect to file with open(string, File::RDONLY)
[string, open_mode] : redirect to file with open(string, open_mode, 0644)
[string, open_mode, perm] : redirect to file with open(string, open_mode, perm)
FD is one of follows
:in : the file descriptor 0 which is the standard input
:out : the file descriptor 1 which is the standard output
:err : the file descriptor 2 which is the standard error
integer : the file descriptor of specified the integer
io : the file descriptor specified as io.fileno
다음 옵션은 현재 지원되지 않습니다.
options: hash
resource limit: resourcename is core, cpu, data, etc. See Process.setrlimit.
:rlimit_resourcename => limit
:rlimit_resourcename => [cur_limit, max_limit]
umask:
:umask => int
redirection:
value:
[:child, FD] : redirect to the redirected file descriptor
file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not
:close_others => false : inherit fds (default for system and exec)
:close_others => true : don't inherit (default for spawn and IO.popen)
Posix::Spawn::Child, Posix::Spawn#spawn, Posix::Spawn#system 및 Posix::Spawn#popen4에서 제공하는 :chdir
옵션은 posix_spawn(2) 시스템 호출로 생성된 프로세스이므로 스레드로부터 안전하지 않습니다. 호출 프로세스의 작업 디렉터리를 상속받습니다. posix-spawn gem은 자식 프로세스를 생성하기 직전과 직후에 호출 프로세스의 작업 디렉터리를 변경하여 시스템 호출의 이러한 제한을 해결합니다.
저작권(c): Ryan Tomayko 및 Aman Gupta.
라이선스 및 재배포에 대한 자세한 내용은 COPYING
파일을 참조하세요.