Can I get data back from a fork?

Hi:

Is there a way to get data back from a fork?
Here is a little code snippet. I think I understand
what it is doing and why it is not working, but
I don’t have much experience in this area.

class Batch
def initialize
@Job = Struct.new(“Job”, :pid, :result, :cmd)
@job_table = {}
end

def launch
job.pid = Process.fork { redirect(job) }
@job_table[pid] = job
ensure
wait
end

def redirect(job)
… setup stuff
job.result = system(job.cmd)
end

def wait
loop {
begin
pid, rtn_status = Process.wait2
job = @job_table[pid]
job.result #=> is empty
rescue StandardError => err
break
end
}
end

def add_command
…add command
end
end#class Batch

I want to be able to store the result status from the system
call, but setting it inside redirect does not seem to work.
I checked and the objects have the same id, so I am
not sure why I can’t set the result status.

Any info would be greatly appreciated.

Thanks

···


Jim Freeze
If only I had something clever to say for my comment…
~

I should probably clarify:

def launch
job.pid = Process.fork { redirect(job) }
@job_table[pid] = job
ensure
wait
end

def redirect(job)
… setup stuff
job.result = system(job.cmd) #=> job.result has a value here
end

def wait
loop {
begin
pid, rtn_status = Process.wait2
job = @job_table[pid]
## We get here after system and redirect return

···

On Wed, Jul 24, 2002 at 10:14:13PM +0900, Jim Freeze wrote:

  job.result                      #=> job.result is empty. Why?
rescue StandardError => err
  break
end

}
end


Jim Freeze
If only I had something clever to say for my comment…
~

Jim Freeze schrieb:

Is there a way to get data back from a fork?
[codesnippet]
I want to be able to store the result status from the system
call, but setting it inside redirect does not seem to work.
I checked and the objects have the same id, so I am
not sure why I can’t set the result status.

It is because the objects live in two different
processes, as this is the meaning of fork.

To interchange information between this two
processes you have to create a interprocess
communication, normally via pipes.

Look in the pickaxe at IO#pipe
(Ch. 22, Built-in classes)

there you can find the following example:

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

the parent process receives the
child process id as result of fork and
goes into the ‘then’ branch.
The child process receives nil as
result of the fork and goes into
the ‘else’ branch.

because of the first line
rd, wr = IO.pipe

the two processes use the created pipe
the parent closes the writer first,
the child closes the reader.
(for details see the pickaxe paragraph).

then the child writes “Hi Dad” into the
pipe which is read by the parent.

HTH

Det

Hi,

···

In message “Can I get data back from a fork?” on 02/07/24, Jim Freeze jfreeze@freebsdportal.com writes:

Is there a way to get data back from a fork?

You have to use either pipe (between parent and child processes) or
thread (instead of fork).

						matz.

The problem is that when you fork, you are creating a new process. So,
sure, the two objects may have the same ID, but it is the same ID in two
seperate processes.

 So, any way, to do what you want you have to have some way to get

the processes to talk to eachother using some kind of IPC. The most
common thing to do would be to use pipes. The other option would be to
use threads instead of seperate processes. Threads are similar, except
that the variables are all shared between the two threads of execution so
there is no need for IPC.

          --Nathan Ricci
···

On Wed, 24 Jul 2002 13:15:06 +0000, Jim Freeze wrote:

Hi:

Is there a way to get data back from a fork? Here is a little code
snippet. I think I understand what it is doing and why it is not
working, but I don’t have much experience in this area.

class Batch
def initialize
@Job = Struct.new(“Job”, :pid, :result, :cmd) @job_table = {}
end

def launch
job.pid = Process.fork { redirect(job) } @job_table[pid] = job
ensure
wait
end

def redirect(job)
… setup stuff
job.result = system(job.cmd)
end

Wow, Thanks for all the help.
So far I count three suggestions,

use exec
use pipe
use thread

Being a novice at this, I would like to ask for some
clarification of which might be best for me to investigate
first. But first, let me point out that the current
implementation fork is inside an #each loop:

class Batch

def launch
@jobs.each { |job|
job.pid = Process.fork { redirect(job) }
@job_table[pid] = job
}
ensure
wait
end#launch
end#Batch

In this case, I think that pipe may have to be excluded.
Is that so?
What does exec give me that system doesn’t?
If I use thread (and system or exec), won’t each
thread be blocked by the call to system/exec?

Thanks

···


Jim Freeze
If only I had something clever to say for my comment…
~

job.pid = Process.fork { redirect(job) }

   job is created in a process

def redirect(job)
job.result = system(job.cmd) #=> job.result has a value here

   you modify `job' in *another* process

job.result #=> job.result is empty. Why?

   you retrieve the value that was assigned in the initial process

   `job' is not a shared variable

Guy Decoux

This was mentioned in passing, but also shared memory via the
sysvipc library.

···

On Wed, Jul 24, 2002 at 11:58:22PM +0900, Jim Freeze wrote:

Wow, Thanks for all the help.
So far I count three suggestions,

use exec
use pipe
use thread


Alan Chen
Digikata LLC

That is what I figured, but I when I printed out the job.id for
both processes, they were the same. Was that just a coincidence?

Jim

···

On Wed, Jul 24, 2002 at 10:59:15PM +0900, ts wrote:

job.pid = Process.fork { redirect(job) }

job is created in a process

def redirect(job)
job.result = system(job.cmd) #=> job.result has a value here

you modify `job’ in another process

job.result #=> job.result is empty. Why?

you retrieve the value that was assigned in the initial process

`job’ is not a shared variable


Jim Freeze
If only I had something clever to say for my comment…
~

Another question. Do you know of a simple way to propagate data back
to the original process?

···

On Wed, Jul 24, 2002 at 10:59:15PM +0900, ts wrote:

job.pid = Process.fork { redirect(job) }

job is created in a process

def redirect(job)
job.result = system(job.cmd) #=> job.result has a value here

you modify `job’ in another process

job.result #=> job.result is empty. Why?

you retrieve the value that was assigned in the initial process

`job’ is not a shared variable


Jim Freeze
If only I had something clever to say for my comment…
~

Sure, spit out the data on stdout and have the parent read it back in :slight_smile:

Tom.

···

On Wed, Jul 24, 2002 at 10:59:15PM +0900, ts wrote:

job.pid = Process.fork { redirect(job) }

job is created in a process

def redirect(job)
job.result = system(job.cmd) #=> job.result has a value here

you modify `job’ in another process

job.result #=> job.result is empty. Why?

you retrieve the value that was assigned in the initial process

`job’ is not a shared variable

Another question. Do you know of a simple way to propagate data back
to the original process?


.^. .-------------------------------------------------------.
/V\ | Tom Gilbert, London, England | http://linuxbrit.co.uk |
/( )\ | Open Source/UNIX consultant | tom@linuxbrit.co.uk |
^^-^^ `-------------------------------------------------------’

That is what I figured, but I when I printed out the job.id for
both processes, they were the same. Was that just a coincidence?

Well, the 2 processes know the variable defined in the parent process but
the parent process can access the variable modified in the child

Guy Decoux

Another question. Do you know of a simple way to propagate data back
to the original process?

Shared memory, it exist a module sysvipc in RAA

Or use pipe

Guy Decoux

Hi,

···

At Wed, 24 Jul 2002 23:09:17 +0900, Jim Freeze wrote:

Another question. Do you know of a simple way to propagate data back
to the original process?

Use exec instead of system.


Nobu Nakada

Well, the 2 processes know the variable defined in the parent process but
the parent process can access the variable modified in the child

                       ^^^
                      cannot

Guy Decoux

p.s.: you have really a "strange" language :-))