Jednym z problemów jest konieczność użycia Process.wait
, aby poczekać na zakończenie rozwidlonych procesów. Drugi polega na tym, że nie można wykonywać komunikacji międzyprocesowej za pomocą zmiennych. Aby to zobaczyć:
@one = nil
@two = nil
@hash = {}
pidA = fork do
sleep 1
@one = 1
@hash[:one] = 1
p [:one, @one, :hash, @hash] #=> [ :one, 1, :hash, { :one => 1 } ]
end
pidB = fork do
sleep 2
@two = 2
@hash[:two] = 2
p [:two, @two, :hash, @hash] #=> [ :two, 2, :hash, { :two => 2 } ]
end
Process.wait(pidB)
Process.wait(pidA)
p [:one, @one, :two, @two, :hash, @hash] #=> [ :one, nil, :two, nil, :hash, {} ]
Jednym ze sposobów komunikacji międzyprocesorowej jest użycie rury (IO::pipe
). Otwórz go przed rozwidleniem, a następnie po obu stronach widelca zamknij jeden koniec rury.
Od ri IO::pipe
:
rd, wr = IO.pipe
if fork
wr.close
puts "Parent got: <#{rd.read}>"
rd.close
Process.wait
else
rd.close
puts "Sending message to parent"
wr.write "Hi Dad"
wr.close
end
_produces:_
Sending message to parent
Parent got: <Hi Dad>
Jeśli chcesz podzielić zmienne używać wątków:
@one = nil
@two = nil
@hash = {}
threadA = Thread.fork do
sleep 1
@one = 1
@hash[:one] = 1
p [:one, @one, :hash, @hash] #=> [ :one, 1, :hash, { :one => 1 } ] # (usually)
end
threadB = Thread.fork do
sleep 2
@two = 2
@hash[:two] = 2
p [:two, @two, :hash, @hash] #=> [ :two, 2, :hash, { :one => 1, :two => 2 } ] # (usually)
end
threadA.join
threadB.join
p [:one, @one, :two, @two, :hash, @hash] #=> [ :one, 1, :two, 2, :hash, { :one => 1, :two => 2 } ]
Jednak nie jestem pewien, czy będzie Ci gwintowania żadnych korzyści, gdy jesteś IO granica.
Czy jesteś pewien, że to YAML zabiera trochę czasu? Jeśli tak, czy próbowałeś załadować go za pomocą Psych, a nie Syck? –