How to make C++ code fork-safe? - Unix

This is a discussion on How to make C++ code fork-safe? - Unix ; William Ahern writes: > Rainer Weikusat wrote: >> William Ahern writes: >> > Andrey wrote: >> >> Threads are invented to provide finer grained parallelism then >> >> processes do. >> >> I think it would be kind of inconvenient ...

+ Reply to Thread
Page 2 of 2 FirstFirst 1 2
Results 21 to 22 of 22

Thread: How to make C++ code fork-safe?

  1. Re: How to make C++ code fork-safe?

    William Ahern writes:
    > Rainer Weikusat wrote:
    >> William Ahern writes:
    >> > Andrey wrote:
    >> >> Threads are invented to provide finer grained parallelism then
    >> >> processes do.
    >> >> I think it would be kind of inconvenient to implement Event-Dispater
    >> >> (for GUI) as a separate process.
    >> >
    >> > Exactly. Inconvenient for the black hats, even.

    >> A German proverb goes 'Was der Bauer nicht kennt, dass frisst er
    >> nicht' ("a farmer won't eat what he isn't used to").

    >> The interface-part of a GUI-application is usually structured around an
    >> event dispatching loop. Events represent either user input (mouse
    >> movements, keypresses) or are synthetically generated in reaction to
    >> 'environmental changes' (eg a redraw-event sent to some application
    >> because one of its windows has been uncovered because another window
    >> was moved). The interface part of such an application has soft
    >> realtime requirements because it needs to react whenever the user does
    >> something. Therefore, it is imperative that no 'lenghty' calculations
    >> or anything else consuming 'a lot of time' (such as blocking for I/O)
    >> take place in the event processing code. The usual way to solve this
    >> would be to do any such lengthy operation from a separate thread while
    >> the event handling thread continues to process ecents.

    > Indeed that is the usual way. I'm unsure why its not more common to employ
    > multiple processes, using a more structured and constrained dispatching
    > mechanism between processes, and isolating the code doing prolonged
    > calculations (often on opaque input data, often untrusted opaque input
    > data). I can think of web browers, e-mail clients, image viewing or
    > manipulation applications, audio/video applications... I could go on forever
    > where this is a prima facie preferred choice absent factors like
    > convenience.

    This is an argument which would equally well apply to single-threaded
    processes. Eg why doesn't tar process 'untrusted archives' in a
    second, sandboxed process, which would be 'cleanly separated' from the
    part processing the command-line options? And this can be taken one
    step further: Assuming there was a reason why processing something in
    a process separated from the interface process would generally be a
    better choice, it should apply to the second process, two, which could
    (for the same reasons) just provide and interface between the first
    process and a third process, which would do the actual processing,
    except that, of course ... finally ending at the ultimate conclusion
    that processing of untrusted data better be avoided due the risks
    associated with it.

    Given that the data is to be processed, this would be a red herring
    and semantically reduce to "why aren't applications requiring internal
    concurrency just always written using multiple processes", with the
    answer you have provided yourself: Because this would be really
    inconvenient for certain applications, for instance those, which would
    need to share a large amount of state among closely related
    'schedulable entities'. The same way it would be inconvenient to not
    use a computer for payroll processing, but do it manually, which would
    work as fine as it always did.

  2. Re: How to make C++ code fork-safe?

    Arkadiy wrote:

    > Supposedly you have a global object (singleton, etc.). To make it
    > thread-safe you lock some of its operations. In the middle of such
    > operation the object may be in an inconsistent state. Let's say a
    > fork is issued from another thread during such an operation (most
    > likely the thread calling fork() does not lock your global object).
    > It copies the object into the child process while it is in the middle
    > of something... Later on it crashes in the destructor when the child
    > is terminated.

    You just did a few little things wrong. For example, why did you try
    to terminate the child normally rather than calling 'exec' or
    terminating abnormally?

    The code after 'fork' has to follow a set of rules or, as you see,
    chaos results. This means 'fork' can only be used for limited purposes
    and not for others.

    > Even better, recall the problem with the double-check pattern
    > (described in
    > Looks like this problem directly applies to fork() if it is issued
    > from another thread after the pointer is assigned but before the
    > object is initialized.

    If you call 'fork' and the code in both paths deal with the same
    object, they should be smart enough to put the object in a consistent
    state before calling 'fork'.

    > Now I am wondering if there exist any rules that can be applied to
    > make your C++ code fork-safe? Or does the usage of fork() itself
    > needs to be limited?

    After a 'fork' and before an 'exec', pay attention to anything that
    might be used by both processes. Put it in a consistent, safe state
    before the 'fork'. You can't just call 'fork' and let both processes
    continue doing everything the original was doing, but this really
    should be common sense, since you can't, for example, turn one TCP
    connection to a web server into two independent connections just
    because someone called 'fork'. That would be impossible.


+ Reply to Thread
Page 2 of 2 FirstFirst 1 2