2009-10-22 10 views
10

Ryan Tomayko poruszył burzę ogniową z this post o użyciu poleceń sterujących procesem Unix.Używanie uniksowych metod sterowania procesami w Rubim

Powinniśmy robić więcej tego. O wiele więcej. Mówię o fork (2), execve (2), pipe (2), socketpair (2), select (2), kill (2), sigaction (2), i tak dalej i tak dalej. To są nasi przyjaciele. Tak bardzo chcą nam tylko pomóc.

Mam bitowego kodu (a delayed_job klona dla DataMapper myślę że pasowałby rację z tym, ale nie jestem jasne, w jaki sposób skorzystać z wymienionych poleceń. Wszelkie pomysły jak poprawić ten kod?

def start 
    say "*** Starting job worker #{@name}" 
    t = Thread.new do 
    loop do 
     delay = Update.work_off(self) 
     break if $exit 
     sleep delay 
     break if $exit 
    end 
    clear_locks 
    end 

    trap('TERM') { terminate_with t } 
    trap('INT') { terminate_with t } 

    trap('USR1') do 
    say "Wakeup Signal Caught" 
    t.run 
    end 
end 

Odpowiedz

3

Ahh tak ... niebezpieczeństwa „Musimy zrobić więcej tego”, nie wyjaśniając, co każdy z tych czy iw jakich okolicznościach pan by ich używać. na coś podobnego delayed_job może nawet używać fork nie wiedząc, że używasz fork. Powiedziałeś, że to naprawdę nie ma znaczenia, Ryan mówił o używaniu fork dla serwerów preforkujących. delayed_job użyłby fork do przekształcenia procesu w demona. Takie same wywołania systemowe, różne cele. Uruchamianie delayed_job na pierwszym planie (bez fork) w tle (z fork) spowoduje nieznaczną różnicę w wydajności.

Jednak, jeśli napiszesz serwer, który akceptuje równoczesne połączenia, teraz rada Ryana jest odpowiednia dla pieniędzy.

  • fork: tworzy kopię oryginału procesu
  • execve: zatrzymuje wykonywany bieżącego pliku i rozpoczyna wykonywanie nowego pliku w tym samym procesie (bardzo użyteczne w zadaniach natarcia)
  • pipe: tworzy rurę (dwa deskryptory plików, po jednym dla odczytu, jeden dla zapisu)
  • socketpair: jak rury, ale dla gniazd
  • select: niech poczekać na jedną lub więcej z wielu deskryptorów plików do odczytu y z timeout
  • kill: służy do wysyłania sygnału do procesu
  • sigaction: pozwala zmienić to, co się dzieje, gdy proces otrzyma sygnał
+0

Więc zamiast tworzyć (zielony) wątek, mógłbym zamiast tego użyć fork (2) i odzyskać PID. Tak wiele zrobiłem. Jak mam pracować z blokiem dla pułapki ("USR1"), który budzi wątek, gdy nowe zadanie trafi do kolejki? Jak utworzyć więcej niż jeden proces i zachęcić ich do optymalnego wycofania kolejki. Magia wydaje się być w rurze i wybierz, ale nie rozumiem zawiłości. Mogę użyć klejnotu daemona do stworzenia procesu demona, który używa widelca pod maską. Chcę uruchomić niektóre procesy podrzędne, aby uruchomić kolejkę. –

+0

Zależy od tego, co oznacza "praca" w tym kontekście. Jeśli "praca" to I/O, może być inna i tak, "wybierz" jest ważne. Wolę projektować kolejki pracy w taki sposób, aby praca mogła być wykonywana w dowolnej kolejności. Jeśli więc jednostka pracy nr 1 zostanie wykonana równocześnie z jednostką pracy nr 2, nie stanowi to problemu. Co do klejnotów demonów ... używałem go, ale teraz używam 'fork' bezpośrednio lub używam biblioteki ChainGang.Zauważyłem, że demony ukrywały zbyt wiele ważnych rzeczy i nie było potrzeby, aby coś było nie tak trudne. Zauważ, że ChainGang ma bardzo wysoką jakość alfa. –

+0

Zasadniczo, martwienie się "optymalnym wycofaniem kolejki" nie ma większego sensu w większości kontekstów. Albo pracujesz z I/O, w takim przypadku prawdopodobnie nie używasz kolejki 'delayed_job', albo robisz rzeczy jako dyskretne jednostki pracy, w którym to przypadku' select' i 'pipe' nie robią żadnych sens. Tak czy owak, właściwym sposobem na zajęcie się kolejką pracy jest złapanie wszystkiego, co jest na górze, kiedy będziesz wolny. A jeśli nic tam nie ma, prawdopodobnie po prostu zablokujesz, dopóki nie będzie. –

Powiązane problemy