복붙노트

[RUBY-ON-RAILS] Process.fork를 대체 Process.spawn 사용

RUBY-ON-RAILS

Process.fork를 대체 Process.spawn 사용

내 개발 환경 1.9.3p125 (RubyInstaller) 루비를 실행하는 Windows 시스템과 3.2.8 레일.

시간을 제공하고 타사 보석을 사용하는 경우 다시, Windows에서 포크 ()의 부족이다 한 가지 문제. 이는 최근 인해 포크에 대한 의존도에, 꽤 많이 (이 같은) 분산 된 테스트 실행 보석을 사용하는 내 능력을 방해하고있다.

StackOverflow의 일부 오래된 질문은이 같은 문제의 해결 방법을 찾기 위해 시도했지만 루비에 Process.spawn를 추가하기 전에 하나 있었다, 또는 다른 이유로, 루비의 이전 버전을 사용하도록 강요 사람들이었다있다.

제안 된 솔루션 중 하나는 단순히 이것에 대한 질문 벗어 포크 () 지원을 얻기 위해 Cygwin에서 사용하는 것입니다 - 내가 그 전에 완전히 리눅스로 전환하는 것을 선호 생각합니다.

또 다른 제안 된 솔루션은 포크 () 지원을 얻기 위해는 Win32 프로세스 보석을 사용하고있다. 포크 지원은 최신 버전 (0.7.0)에서 제거하고, 적어도 분산 중 하나를 실행하기위한, 작동하지 않는 지원 포크 (정렬의) 수행 다음으로 오래된 버전 (0.6.6)를 사용했다 내가 시도하는 것이 보석 (거의 모든 이들의 Spork, 병렬 테스트, 히드라, Specjour를) 테스트. 흥미롭게도, 보석의 암시의 저자는, 추가 정보에 Process.spawn에 Process.fork에 대한 수용 가능한 해결되고.

나는 많은 정보 중 하나를 의미, 또는 산란 루비 1.9, Windows에서 포크에 대한 교체로 사용될 수 있다는 것을 무조건적인 진술 보았다. 나는 기본적으로 성공하지, 참조 된 보석의 여러 가지에 Process.spawn와 Process.fork를 대체하는 노력이와 시간 재생의 공정한 금액을 보냈습니다. 아마도 동작이 유사하지만, 정확히 동일하지 그 날 것으로 보인다. 예를 들어, 포크 단순히 않습니다, 또는 같은 방법으로 전체 프로세스가 지정된 인수로 새로운 프로세스를 생성 산란 실제로 복사 여부 불분명하다. 스폰 방법도 인수, 또는 단지 시스템 명령과 다른 루비 방법을 수용할지 여부에 관해서는 또한 명확하지 않다. 워드 프로세서는 단지 명령임을 암시하는 것 같다,하지만 방법은 (정렬의) 작동하는 것 같다,하지만 난 잘못 일을 할 수있다. 나는 몇 가지를 들면, 포크 그냥 스레딩을 지원하지 않은 이전의 루비 버전의 "싼 스레드"를 만드는 데 사용 된 것으로 생각합니다. 그러나, 이러한 분산 테스트 보석 합법적으로 프로젝트 상태를 유지하기 위해, 포크 ()의 모든 기능에 의존 할 수 있으며, 모든 테스트에 대한 전체 루비 환경을로드하지 않는 것 같다. 이것은 내 정상적인 프로그램의 의무와 경험의 비트 외부, 그래서 몇 가지 잘못된 가정을 할 수있다.

그래서, 내 질문은, Process.spawn 모든 경우에, Process.fork과 같은 결과를 달성하기 위해 상대적으로 간단하게 사용할 수 있습니까? 난 안 의심하기 시작하고,하지만 만약 그렇다면, 사람이 하나가 변화를 만들어 가겠어요 방법의 예를 게시하시기 바랍니다 수 있을까?

해결법

  1. ==============================

    1.편집 : () 산란로 대체 할 수 포크 ()의 하나의 공통 사용 사례가있다 - 포크 () - 간부 인 () 콤보. 그들은 다른 프로세스를 생성 할 나이 (현대) UNIX 응용 프로그램, 의지 첫번째 포크, 그리고 많은 exec를 호출 (간부을 대체 서로 현재 프로세스)를 확인하십시오. 이 산란으로 대체 할 수있다 왜이하지 실제로 필요하지 포크 (), (). 그래서 이건:

    편집 : () 산란로 대체 할 수 포크 ()의 하나의 공통 사용 사례가있다 - 포크 () - 간부 인 () 콤보. 그들은 다른 프로세스를 생성 할 나이 (현대) UNIX 응용 프로그램, 의지 첫번째 포크, 그리고 많은 exec를 호출 (간부을 대체 서로 현재 프로세스)를 확인하십시오. 이 산란으로 대체 할 수있다 왜이하지 실제로 필요하지 포크 (), (). 그래서 이건:

    if(!fork())
      exec("dir")
    end
    

    로 대체 할 수있다 :

    Process.spawn("dir")
    

    보석의이 같은 포크 ()를 사용하는 경우, 수정이 용이하다. 그렇지 않으면 거의 불가능하다.

    편집 : 포크의 이유는 Win32 프로세스 '구현 () (필자는 문서에서 말할 수까지로), 그것은 기본적으로 산란이 (), 포크하지 않은 () 모두에있을 일이 즉하지 않습니다.

    아니, 나는 그것을 할 수 있다고 생각하지 않습니다. 당신은 Process.spawn 기본 빈 상태와 네이티브 코드로 새로운 프로세스를 생성, 참조하십시오. 그래서, 나는 그것이 클론 어떤 현재 프로세스의 '상태하지 않습니다, 디렉토리를 실행 비어있는 새 프로세스를 시작합니다 Process.spawn 같은 ('디렉토리 ')을 할 수있다. 아이 연결 - 그것은 당신의 프로그램 만 연결이 부모입니다.

    당신은 포크 ()는 매우 낮은 수준의 호출이다, 참조하십시오. 첫째, 새로운 프로세스가 정확히 복제 레지스터 상태로 생성됩니다 예를 들어, 리눅스에 기본적으로 무엇을 포크 ()이있다. 그리고, 리눅스는 부모 프로세스 '의 모든 페이지에 복사 (copy-on-write) 참조한다. 리눅스는 다른 프로세스 플래그를 복제합니다. 물론,이 모든 작업은 커널 만 수행 할 수 있으며, 윈도우 커널은 시설이 할 필요가 없다 (그리고 하나에 패치 할 수 없습니다).

    지원 같은 - 기술적으로, 네이티브 프로그램 () 포크 어떤 종류의 OS가 필요합니다. 이 포크처럼 뭔가를 위의 코드의 모든 층은 층의 협력이 필요합니다 (). 네이티브 C 코드를 포크로 커널의 협력을 필요로하는 동안 그래서, 루비는 이론적으로 만 포크를 할 인터프리터의 협력을 필요로한다. 그러나, 루비 인터프리터는 포크를 구현하기 위해 반드시 것 스냅 샷 / 복원 기능을 가지고 있지 않습니다. 이것 때문에, 통상 루비 포크 인터프리터 자체가 아니라 루비 프로그램을 분기함으로써 달성된다.

    당신이 정지를 추가 할 루비 인터프리터를 패치 할 수 있다면 / 시작 및 스냅 샷 / 복원 기능을하면서 그럼, 그렇지 않으면 그것을 할,하지만 수 있을까? 그렇게 생각하지 않아요.

    그래서 옵션은 무엇입니까? 이것은 내가 생각할 수있는 것입니다 :

    편집 1 : 나는 특별한 Cygwin에서 프로세스 테이블을 포함로, 어떤 기록 중 복사, 매우 비효율적 수 없다, Cygwin에서의 포크를 사용하는 것이 좋습니다 않을 것입니다. 또한, 점프 앞뒤로 및 복사를 많이 많이 포함한다. 가능하다면 그것을 피하십시오. Windows가 주소 공간을 복사 할 기능을 제공하지 않기 때문에 또한, 포크 가능성이 높다 실패하기, 그리고 꽤 많은 시간이 (여기 참조)합니다.

  2. from https://stackoverflow.com/questions/12220024/using-process-spawn-as-a-replacement-for-process-fork by cc-by-sa and MIT license