문제

만약 내가한다면

Process.fork do 
  x 
end 

X를 반환 한 X를 어떻게 알 수 있습니까 (예 : True/Fase/String)?

(파일/데이터베이스에 쓰는 것은 옵션이 아닙니다 ...)

도움이 되었습니까?

해결책 3

나는 길을 따라 찾은 모든 솔루션 (사용자 종료 + 배관-버퍼와 같은 다른 문제)을 루비 평행 보석. 이제 그것은 다음과 같이 쉽습니다.

results = Parallel.map([1,2,3],:in_processes=>4) do |i|
  execute_something(i)
end

또는

results = Parallel.map([1,2,3],:in_threads=>4) do |i|
  execute_something(i)
end

다른 팁

우리는 실제로이 문제를 처리해야했습니다 레일 격리 테스트. 나는 그것에 대해 약간 게시했습니다 내 블로그에서.

기본적으로, 당신이하고 싶은 것은 부모와 자녀의 파이프를 열고 아이가 파이프에 글을 쓰게하는 것입니다. 다음은 아동 프로세스에서 블록의 내용을 실행하고 결과를 되 찾는 간단한 방법입니다.

def do_in_child
  read, write = IO.pipe

  pid = fork do
    read.close
    result = yield
    Marshal.dump(result, write)
    exit!(0) # skips exit handlers.
  end

  write.close
  result = read.read
  Process.wait(pid)
  raise "child failed" if result.empty?
  Marshal.load(result)
end

그런 다음 실행할 수 있습니다.

do_in_child do
  require "some_polluting_library"
  SomePollutingLibrary.some_operation
end

자식을 요구하는 경우 부모의 해당 라이브러리에 액세스 할 수 없으므로이 방법을 사용하여 해당 유형의 개체를 반환 할 수 없습니다. 그러나 둘 다 사용할 수있는 모든 유형을 반환 할 수 있습니다.

또한 여기에 많은 세부 사항이 있습니다 (read.close, Process.wait2(pid))는 주로 하우스 키핑 세부 사항이므로, 이것을 많이 사용하면 재사용 할 수있는 유틸리티 라이브러리로 옮길 것입니다.

마지막으로, 이것은 포크를 지원하지 않기 때문에 Windows 또는 Jruby에서는 작동하지 않습니다.

모든 답변에 감사드립니다. 솔루션을 시작하고 실행했지만 여전히 비 포크 환경을 처리하는 방법을 확인해야하지만 지금은 작동합니다 :)

read, write = IO.pipe
Process.fork do
  write.puts "test"
end
Process.fork do
  write.puts 'test 2'
end

Process.wait
Process.wait

write.close
puts read.read
read.close

당신은 그것을 행동으로 볼 수 있습니다 @ Parallel_Specs Rails 플러그인

예, 내부 블록을 실행하기 위해 하위 프로세스를 만들 수 있습니다.

추천합니다 그만큼 aw 보석:

Aw.fork! { 6 * 7 } # => 42

물론 부작용을 방지합니다.

arr = ['foo']
Aw.fork! { arr << 'FUU' } # => ["foo", "FUU"]
arr # => ["foo"]

문서에 따르면 :

블록이 지정되면 해당 블록은 하위 프로세스에서 실행되며 서브 프로세스는 0의 상태로 종료됩니다.

따라서 블록으로 호출하면 0이 반환됩니다. 그렇지 않으면 기본적으로 기능합니다. fork() UNIX에서 시스템 호출 (부모는 새로운 과정의 PID를 받고 자녀가받습니다. nil).

두 개의 UNIX 프로세스 간의 포크 커뮤니케이션은 주로 리턴 코드이며 더 이상 아무것도 아닙니다. 그러나 두 프로세스 사이에 제출 된 스크립터를 열고이 제출자를 통한 프로세스간에 데이터를 전달할 수 있습니다. 이것은 일반적인 UNIX 파이프 방식입니다.

Marshal.dump () 및 Marshal.load () 값을 전달하면 Ruby 프로세스 사이에 Ruby 객체를 쉽게 전달할 수 있습니다.

자녀가 루비 코드의 작은 덩어리가되어야하는 경우 공유 메모리를 사용하여이를 수행 할 수 있습니다. 다음과 같은 것이 작동합니다.

str = 'from parent'

Thread.new do
  str = 'from child'
end

sleep(1)

puts str    # outputs "from child"

동시성은 매우 까다로울 수 있으며, 이런 방식으로 공유 메모리에 액세스하는 것은 이유의 큰 부분입니다. 변수가 있고 다른 프로세스가 당신 아래에서 변경 될 수 있습니다. 매우 조심해야합니다. 또는 더 번거롭지 만 아마도 가장 사소한 코드에 대해서는 더 안전한 파이프를 사용할 수 있으며 임의의 명령을 실행하는 데 사용될 수도 있습니다. 다음은 io.popen의 RDOC에서 바로 다음과 같습니다.

f = IO.popen("uname")
p f.readlines     # outputs "Darwin", at least on my box  :-)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top