Basic Inter process communication question - Unix

This is a discussion on Basic Inter process communication question - Unix ; All, I have some general questions about UNIX/Solaris IPC. I am new to this stuff so Iím not sure I have using the correct techniques in the correct way. So I would appreciate a bit of guidance: I am wondering ...

+ Reply to Thread
Results 1 to 8 of 8

Thread: Basic Inter process communication question

  1. Basic Inter process communication question

    All,

    I have some general questions about UNIX/Solaris IPC. I am new to this
    stuff so Iím not sure I have using the correct techniques in the
    correct way. So I would appreciate a bit of guidance:

    I am wondering what is the best way of making a parent process fork a
    child process and the wait for the child process to complete.

    The twist is that I donít want the memory of the parent process to be
    copied to the child (as is huge and holds lots of resources like
    database connections).

    I want the child to make call-back to the parent process to
    interrogate the database all call functions which required data held
    in the parents address space.

    The reason I want this perverse framework is I have to call some very
    complex third party C++ code written by another group and sometimes
    this crashes due to memory problems. This is very rare, and itís
    usually because of some new weird case itís trying to process. So itís
    very hard for them to test every case before hand. I am not the owner
    of the code, but I do recompile it. I work in C++ too.

    Anyway, I cannot fix the third party code I just have to accept that
    sometimes it fails.

    I would like to insulate calls to this code from the rest of my system
    so when the third party code crashes it does not bring everything down
    with it.

    I have tried setting up signal handlers for segmentation faults and
    bus error but that sometimes results in a system with does not crash
    but is unstable. I think the failure in the third party code is
    corrupting my system.

    So I am thinking: If I run their code in a separate process should it
    crash then it will not impact on the main system and everything will
    stay on its feet.

    Where the third party code needs to call functions (which it will need
    a few) in the main process. The child can use some kind of blocking
    IPC that copys the arguments to a POD in shared memory and signal the
    parent process to perform the work and signal back when itís done.
    This way the two processes are independent and a problem in the child
    will not propagate to the parent.

    So I would appreciate it if people could give me a few pointers:

    1) Am I Mad? Will this really work?

    2) How should the parent wait for the child? Do you just repeatedly
    call waitpid with WNOHANG in a loop or is it better to sleep and wait
    for the child to a send a signal?

    3) How would the child indicate which callback it wants to call? I
    assume that the child can send a signal when it needs to invoke a
    callback and then uses a semaphore to indicate which one it wants.

    4) The arguments for the callbacks are relatively small and C POD
    types not C++ so I they can be held in shared memory.

    Thanks for your time

    stdlib

  2. Re: Basic Inter process communication question

    In article
    <05d03ce1-a391-42dc-a0ae-16ab46c3989a@c60g2000hsf.googlegroups.com>,
    stdlib99@googlemail.com wrote:

    > All,
    >
    > I have some general questions about UNIX/Solaris IPC. I am new to this
    > stuff so IĻm not sure I have using the correct techniques in the
    > correct way. So I would appreciate a bit of guidance:
    >
    > I am wondering what is the best way of making a parent process fork a
    > child process and the wait for the child process to complete.


    There's only one way in standard Unix, the fork() system call to fork a
    child, and the wait*() family of functions to wait for it to complete.

    >
    > The twist is that I donĻt want the memory of the parent process to be
    > copied to the child (as is huge and holds lots of resources like
    > database connections).


    Unix doesn't provide a way to fork without copying. However, the copy
    is just done using virtual memory tricks, it doesn't actually have to
    copy all the memory contents.

    >
    > I want the child to make call-back to the parent process to
    > interrogate the database all call functions which required data held
    > in the parents address space.


    So the parent won't simply "wait for the child process to complete", it
    needs to continue so that it can process these callbacks.

    Message queues seem like a reasonable IPC mechanism for this.

    >
    > The reason I want this perverse framework is I have to call some very
    > complex third party C++ code written by another group and sometimes
    > this crashes due to memory problems. This is very rare, and itĻs
    > usually because of some new weird case itĻs trying to process. So itĻs
    > very hard for them to test every case before hand. I am not the owner
    > of the code, but I do recompile it. I work in C++ too.
    >
    > Anyway, I cannot fix the third party code I just have to accept that
    > sometimes it fails.
    >
    > I would like to insulate calls to this code from the rest of my system
    > so when the third party code crashes it does not bring everything down
    > with it.
    >
    > I have tried setting up signal handlers for segmentation faults and
    > bus error but that sometimes results in a system with does not crash
    > but is unstable. I think the failure in the third party code is
    > corrupting my system.


    You generally can't recover from these types of errors, as they almost
    always are the result of memory corruption. By the time the errors
    happen, you're already screwed.

    >
    > So I am thinking: If I run their code in a separate process should it
    > crash then it will not impact on the main system and everything will
    > stay on its feet.
    >
    > Where the third party code needs to call functions (which it will need
    > a few) in the main process. The child can use some kind of blocking
    > IPC that copys the arguments to a POD in shared memory and signal the
    > parent process to perform the work and signal back when itĻs done.
    > This way the two processes are independent and a problem in the child
    > will not propagate to the parent.
    >
    > So I would appreciate it if people could give me a few pointers:
    >
    > 1) Am I Mad? Will this really work?


    I think so.
    >
    > 2) How should the parent wait for the child? Do you just repeatedly
    > call waitpid with WNOHANG in a loop or is it better to sleep and wait
    > for the child to a send a signal?


    When a child process exits, the OS automatically sends a SIGCHLD signal.

    > 3) How would the child indicate which callback it wants to call? I
    > assume that the child can send a signal when it needs to invoke a
    > callback and then uses a semaphore to indicate which one it wants.


    As I mentioned above, I suggest using a message queue. The callback can
    be in the message header.

    >
    > 4) The arguments for the callbacks are relatively small and C POD
    > types not C++ so I they can be held in shared memory.


    Or you could just put them in the message in the message queue.

    >
    > Thanks for your time
    >
    > stdlib


    --
    Barry Margolin, barmar@alum.mit.edu
    Arlington, MA
    *** PLEASE post questions in newsgroups, not directly to me ***
    *** PLEASE don't copy me on replies, I'll read them in the group ***

  3. Re: Basic Inter process communication question

    Barry Margolin writes:

    > In article
    > <05d03ce1-a391-42dc-a0ae-16ab46c3989a@c60g2000hsf.googlegroups.com>,
    > stdlib99@googlemail.com wrote:
    >
    >> All,
    >>
    >> I have some general questions about UNIX/Solaris IPC. I am new to this
    >> stuff so IĻm not sure I have using the correct techniques in the
    >> correct way. So I would appreciate a bit of guidance:
    >>
    >> I am wondering what is the best way of making a parent process fork a
    >> child process and the wait for the child process to complete.

    >
    > There's only one way in standard Unix, the fork() system call to fork a
    > child, and the wait*() family of functions to wait for it to complete.
    >
    >>
    >> The twist is that I donĻt want the memory of the parent process to be
    >> copied to the child (as is huge and holds lots of resources like
    >> database connections).

    >
    > Unix doesn't provide a way to fork without copying. However, the copy
    > is just done using virtual memory tricks, it doesn't actually have to
    > copy all the memory contents.


    Well, some Unixes provide a way: vfork(). This lets the child share its
    memory with the parent; any changes it makes will be seen by the
    parent. This is only intended to be used briefly until the child calls
    exec().

    So if the child's job can be factored out into a separate program, you
    can have the parent use vfork()/exec() to run it. The two can then
    communicate via the IPC mechanisms that Barry mentions.

    You'll have to decide if the overhead of exec()'ing another (possibly
    small) program is better than having a (virtual) copy of the parent
    hanging around.

    >> I want the child to make call-back to the parent process to
    >> interrogate the database all call functions which required data held
    >> in the parents address space.

    >
    > So the parent won't simply "wait for the child process to complete", it
    > needs to continue so that it can process these callbacks.
    >
    > Message queues seem like a reasonable IPC mechanism for this.


    Pipes might also work.

  4. Re: Basic Inter process communication question

    >I have some general questions about UNIX/Solaris IPC. I am new to this
    >stuff so Iím not sure I have using the correct techniques in the
    >correct way. So I would appreciate a bit of guidance:
    >
    >I am wondering what is the best way of making a parent process fork a
    >child process and the wait for the child process to complete.
    >
    >The twist is that I donít want the memory of the parent process to be
    >copied to the child (as is huge and holds lots of resources like
    >database connections).


    Copy-on-write does a pretty good job of eliminating copies except
    for those pages changed by the child. To minimize that, have the
    child exec() something smaller quickly. vfork() was supposed to
    address this problem but I think by now fork() has caught up on
    most systems.

    >I want the child to make call-back to the parent process to
    >interrogate the database all call functions which required data held
    >in the parents address space.
    >
    >The reason I want this perverse framework is I have to call some very
    >complex third party C++ code written by another group and sometimes
    >this crashes due to memory problems. This is very rare, and itís
    >usually because of some new weird case itís trying to process. So itís
    >very hard for them to test every case before hand. I am not the owner
    >of the code, but I do recompile it. I work in C++ too.
    >
    >Anyway, I cannot fix the third party code I just have to accept that
    >sometimes it fails.
    >
    >I would like to insulate calls to this code from the rest of my system
    >so when the third party code crashes it does not bring everything down
    >with it.
    >
    >I have tried setting up signal handlers for segmentation faults and
    >bus error but that sometimes results in a system with does not crash
    >but is unstable. I think the failure in the third party code is
    >corrupting my system.
    >
    >So I am thinking: If I run their code in a separate process should it
    >crash then it will not impact on the main system and everything will
    >stay on its feet.


    Maybe. There is some possibility you're deadlocking on running
    out of virtual memory, which can still get you in trouble.

    >Where the third party code needs to call functions (which it will need
    >a few) in the main process. The child can use some kind of blocking
    >IPC that copys the arguments to a POD in shared memory and signal the
    >parent process to perform the work and signal back when itís done.
    >This way the two processes are independent and a problem in the child
    >will not propagate to the parent.
    >
    >So I would appreciate it if people could give me a few pointers:
    >
    >1) Am I Mad? Will this really work?


    It won't solve all problems, but it does have a chance to work.

    >2) How should the parent wait for the child? Do you just repeatedly
    >call waitpid with WNOHANG in a loop or is it better to sleep and wait
    >for the child to a send a signal?


    Depending on the type of communication needed, a pair of pipes (one
    in each direction) may provide possibilities for not busy waiting
    but not deadlocking either.


    >3) How would the child indicate which callback it wants to call? I
    >assume that the child can send a signal when it needs to invoke a
    >callback and then uses a semaphore to indicate which one it wants.


    I was thinking of a short message written down a pipe, preferably
    of fixed length and sent with one write() call.

    The model I'm thinking of is (the child has only ONE call outstanding
    to the parent at one time):

    (1) Child wants to call function in parent, so it writes a
    message down a pipe.
    (2) Parent reads and decodes message.
    (3) Parent replies with message indicating an answer (which, if
    large, could go into a shared memory segment.
    (4) Child receives message, does something with answer.
    (5) Go to (1).

    If the child exits (it should probably ship a message first saying
    "I'm terminating normally") or crashes, the parent will get EOF on
    the pipe in step (2).

    Whether a lot of this is suitable depends on the interaction between
    parent and child.


    >4) The arguments for the callbacks are relatively small and C POD
    >types not C++ so I they can be held in shared memory.
    >
    >Thanks for your time
    >
    >stdlib




  5. Re: Basic Inter process communication question

    stdlib99@googlemail.com wrote:
    [snip]
    > I am wondering what is the best way of making a parent process fork a
    > child process and the wait for the child process to complete.
    >
    > The twist is that I donít want the memory of the parent process to be
    > copied to the child (as is huge and holds lots of resources like
    > database connections).
    >
    > I want the child to make call-back to the parent process to
    > interrogate the database all call functions which required data held
    > in the parents address space.
    >
    > The reason I want this perverse framework is I have to call some very
    > complex third party C++ code written by another group and sometimes
    > this crashes due to memory problems.

    [snip]

    As others have pointed out, the memory/resource issue you expressed
    concern about might be less of a problem than you think, but one
    solution is to fork() early (ie as part of startup) and have the child
    become your main process. The original process can then fork() again to
    run the third party code inside some sort of IPC wrapper, and can detect
    if either the main process exits (in which case it could clean up and
    exit itself, or perhaps restart everything, if your own code sometimes
    fails or the third process exits (in which case it can recreate it).

    This leaves the problem of the main process noticing that the third
    party code has failed, so it can recover. One idea would be to make the
    original process a server that waits for a connection to a Unix domain
    stream socket, then forks the third process to run the third party code.
    Much as Gordon Burditt described for pipes, the main process will see
    EOF (or a write() failure) on the socket if the third process exits eg
    due to crashing.

    Alex

  6. Re: Basic Inter process communication question

    Thanks to everyone for replying. Iím encourage that my plan *might*
    work.

    The model I propose if that one that was suggested. The child only
    ever has one call outstanding with the parent and waits for a
    response. While the child (parent) is working the parent (child) is
    waiting for the response.

    Unfortunately I should have mentioned that Iím implementing call
    backs for the system which Iím trying to prevent crashing. I cannot
    change the System (easily), so turning it into a server is not really
    an option. To summarise what I want to happen is:

    1) Systems calls my code.
    2) I fork of a process
    3) Run the third party code and calls parent process for data.
    4) If third part code fails child process dies. Calculations are
    aborted and control is returned to the main system (which has not
    crashed)

    I think the two things to decide are:

    1) How to fork off and ensure that the parentís address space is not
    available to the child.
    2) What method of interprocess communication to use.


    How to fork
    ----------------
    I do not want the parentís memory to be available to the child. So In
    some ways IĎd like to do a vfork, but this means the parent process
    will not response to call backs. I donít like the idea of this and
    vfork seems to be deprecated now anyway.

    The overhead of the fork is not that important as the overall
    processing time is rather long.
    So I could do an exec after the fork without a large performance
    impact.
    However I donít want to separate the third party code in a separate
    program which is exce()ed after the fork as I still want the option to
    run the thing in one process and to make this choice at rum time.

    So it actually looks like itís impossible to fork and prevent the
    parentís address space being available with copy on write. I think I
    will have to fork and then if the parentsís address space is accessed
    by the child (which should only happen in error) then the copy will be
    made and the original will not be affected. The only problem comes if
    the area of memory the child accidentally writes to is do with
    resources in which case the insulation I am trying to achieve will not
    be perfect, but itís the best I can do.

    What IPC method to use
    -------------------------------
    Message queues and pipes seem a popular suggestion, and they would
    helpfully deal with some of the synchronisation issues too. Hover I am
    wondering what the overhead of Messages queues is? Depending on how I
    split the logic up there could be a lot of communication between the
    parent and the child. The cost of the initial fork is not important
    but the overhead of IPC is very important in this case. I am concerned
    that Message quests could be slower than shared memory due to the
    overhead of encoding. The amount of data in each call is very small Ė
    a few numbers and a few char arrays. But there could be lots of calls
    so I my intuition tells me that shared memory is a better option
    because I guess there is less overhead (because of less encoding).
    The downside is that I have to roll my own synchronisation, but that
    is OK as the situation here is relatively simple.

    So my questions are:

    1) Is there a way to complete insulate the parents address space e.g a
    non blocking fork.

    2) What is the fastest method of IPC on Solaris. I assume its Shared
    Memory, but is it really that much faster?

    stdlib



  7. Re: Basic Inter process communication question

    stdlib99@googlemail.com wrote:
    > Thanks to everyone for replying. Iím encourage that my plan *might*
    > work.
    >
    > The model I propose if that one that was suggested. The child only
    > ever has one call outstanding with the parent and waits for a
    > response. While the child (parent) is working the parent (child) is
    > waiting for the response.
    >
    > Unfortunately I should have mentioned that Iím implementing call
    > backs for the system which Iím trying to prevent crashing. I cannot
    > change the System (easily), so turning it into a server is not really
    > an option. To summarise what I want to happen is:
    >
    > 1) Systems calls my code.
    > 2) I fork of a process
    > 3) Run the third party code and calls parent process for data.
    > 4) If third part code fails child process dies. Calculations are
    > aborted and control is returned to the main system (which has not
    > crashed)
    >
    > I think the two things to decide are:
    >
    > 1) How to fork off and ensure that the parentís address space is not
    > available to the child.


    There is only one answer to that: exec (probably after closing any
    unnecessary file descriptors).

    I'm not sure you've considered that without an exec(), any pages
    modified in the parent while the child exists (which, if I understand
    the situation correctly, can only be due to handling callbacks from the
    child) will result in them being copied just the same as the child
    changing them.

    > 2) What method of interprocess communication to use.


    You can be fairly confident that the synchronisation in pipes and
    message queues is both efficient and, perhaps more importantly,
    debugged. Shared memory avoids some copying and is more beneficial when
    large amounts of data are being exchanged.

    It seems to me that in your case, there will be a (possibly large)
    number of small exchanges; this suggests that shared memory will not
    offer a substantial advantage in terms of performance.

    Alex

  8. Re: Basic Inter process communication question

    stdlib99@googlemail.com writes:

    > Thanks to everyone for replying. I’m encourage that my plan *might*
    > work.
    >
    > The model I propose if that one that was suggested. The child only
    > ever has one call outstanding with the parent and waits for a
    > response. While the child (parent) is working the parent (child) is
    > waiting for the response.
    >
    > Unfortunately I should have mentioned that I’m implementing call
    > backs for the system which I’m trying to prevent crashing. I cannot
    > change the System (easily), so turning it into a server is not really
    > an option. To summarise what I want to happen is:
    >
    > 1) Systems calls my code.
    > 2) I fork of a process
    > 3) Run the third party code and calls parent process for data.
    > 4) If third part code fails child process dies. Calculations are
    > aborted and control is returned to the main system (which has not
    > crashed)
    >
    > I think the two things to decide are:
    >
    > 1) How to fork off and ensure that the parent’s address space is not
    > available to the child.


    What do you mean by "available"? The child process will be able to see
    the contents of the parent's address space at the time of the fork, so
    that's possibly an issue if the parent had some top secret data that the
    third party code must not be allowed to see, in which case exec() is
    your best option. However, regardless, neither the parent nor the child
    will be able to modify the contents of each other's address space; any
    attempt to modify a shared page will result in a copy being made. So
    any further communication between them has to be via the usual IPC
    mechanisms.

+ Reply to Thread