Why can Glib fork/exec processes with threads? - process

Following is terrible for pthread users include me:
"Why threads can't fork | Hacker News" https://news.ycombinator.com/item?id=8449164
However Glib documents say that it can fork/exec under enabling pthread:
"Threads: GLib Reference Manual" https://developer.gnome.org/glib/stable/glib-Threads.html
"Spawning Processes: GLib Reference Manual" https://developer.gnome.org/glib/stable/glib-Spawning-Processes.html
Why/how can Glib do that?

You can fork() from a pthread, but it may be tricky to do the details right. For example, the forked process memory will contain copies of all the condition variables and mutexes in the original process. Here is a related question, and some guidelines on how to e.g. cleanly release all mutexes held by various threads.
fork in a multithreaded process with lots of state held in threads
Note that the general idea is to fork(), do some cleanup, and then exec().
For a list of async-signal-safe functions that can be called between fork and exec, see this manpage (signal-safety(7))
But my general advice is to make your threaded application simpler - forking with a lot of state to handle in varioius threads is asking for trouble. For example, exec() by design preserves open file descriptors, so if any thread had an open file descriptor, the exec():ed process may unnecessarily carry around that descriptor. Resource leaks are a code smell and generally a sign of sloppy design. Use RAII if you can.

Related

What happens if an MPI process crashes?

I am evaluating different multiprocessing libraries for a fault tolerant application. I basically need any process to be allowed to crash without stopping the whole application.
I can do it using the fork() system call. The limit here is that the process can be created on the same machine, only.
Can I do the same with MPI? If a process created with MPI crashes, can the parent process keep running and eventually create a new process?
Is there any alternative (possibly multiplatform and open source) library to get the same result?
As reported here, MPI 4.0 will have support for fault tolerance.
If you want collectives, you're going to have to wait for MPI-3.something (as High Performance Mark and Hristo Illev suggest)
If you can live with point-to-point, and you are a patient person willing to raise a bunch of bug reports against your MPI implementation, you can try the following:
disable the default MPI error handler
carefully check every single return code from your MPI programs
keep track in your application which ranks are up and which are down. Oh, and when they go down they can never get back. but you're unable to use collectives anyway (see my opening statement), so that's not a huge deal, right?
Here's an old paper (back when Bill still worked at Argonne. I think it's from 2003):
http://www.mcs.anl.gov/~lusk/papers/fault-tolerance.pdf . It lays out the kinds of fault tolerant things one can do in MPI. Perhaps such a "constrained MPI" might still work for your needs.
If you're willing to go for something research quality, there's two implementations of a potential fault tolerance chapter for a future version of MPI (MPI-4?). The proposal is called User Level Failure Mitigation. There's an experimental version in MPICH 3.2a2 and a branch of Open MPI that also provides the interfaces. Both are far from production quality, but you're welcome to try them out. Just know that since this isn't in the MPI Standard, the function prefixes are not MPI_*. For MPICH, they're MPIX_*, for the Open MPI branch, they're OMPI_* (though I believe they'll be changing theirs to be MPIX_* soon as well.
As Rob Latham mentioned, there will be lots of work you'll need to do within your app to handle failures, though you don't necessarily have to check all of your return codes. You can/should use MPI error handlers as a callback function to simplify things. There's information/examples in the spec available along with the Open MPI branch.

Understand "after fork any process settings which will survive an exec may be changed"

Quoted from Wikipedia:
The Microsoft Windows spawn functions are inspired by Unix functions
fork and exec; however, as Windows does not support fork (at least in
the Win32 API; POSIX emulation environments such as Cygwin or SFU do),
the spawn function was supplied as a replacement for the fork-exec
combination.
However, the spawn function, although it deals adequately with the
most common use cases, lacks the full power of fork-exec, since after
fork any process settings which will survive an exec may be changed.
However, in most cases, this deficiency can be made up for by using
the more low-level CreateProcess API.
I was wondering how to understand the reason that Windows spaw() is weaker than Unix fork-exec: "after fork any process settings which will survive an exec may be changed"?
When does the "change" to some process settings happen: between fork and exec or after exec?
In a child process, will the environment variables inherited from its parent process survice exec?
Are there some examples?
Thanks and regards!
The "change" will happen between the fork() and exec(). Quite a lot of the process state is inherited across an exec, see http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html . In particular, file descriptors are inherited (unless they have the close-on-exec bit set).
Typically one uses pipe() and the dup() family of calls to set up pipes and redirect file descriptors. E.g. connecting standard input and output of the child process to a pipe so that the parent process can communicate with the child.

What is the fastest way to write sequential data to disk under Mac OS X?

I need a way to store large data chunks(~1-2MB) at a high rate (~200-300Mbit/s).
After some research I found several options:
aio_write
Direct_IO
Carbon File Manager's PBWriteForkAsync()
default fwrite(), wrapped in a block and dispatched via GCD
NSData's appendData in an NSOperation
...
This wiki page describes the state of aio_write under Linux. What I didn't find was a similar page about the state of aio_write for Mac OS X.
NSOperation or Blocks+GCD seems to be a technique to achieve non-blocking IO. It is used in several open source IO libraries (e.g. https://github.com/mikeash/MAAsyncIO)
Has someone with a similar problem found a suitable solution?
Currently I tend towards PBWriteForkAsync as it takes some 'tuning'parameters. It also should be 64-bit safe.
I don't know MacOS very well, but I'd also try open and write syscalls from unistd.h with the non-blocking option O_NONBLOCK. reference
You should use unbuffered I/O for the writes, in Carbon this is FSWriteFork() with kFSNoCacheBit, in BSD use fcntl() with F_NOCACHE.
Rather than use the system's non-blocking IO, you may want to consider a worker thread to write the blocks sequentially using a queue. This will give you more control and may end up being simpler, particularly if you want to monitor the queue to see if you are keeping up or not.
See here for more information.

how to fork JVM? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java - C-Like Fork?
I wanted to know how is it possible to fork a child JVM from a JDK or even is it possible to do so?
Some frameworks like hadoop fork a child JVM for specific tasks thus Please throw some light on the subject.
Thanks!
Fork is commonly confused with spawn.
Spawn is fork + exec (which means start a process
which replaces the current one and inherits some of
its external resources, such as open sockets).
Spawn is available in Java (via System.exec and the like).
Fork is not in Java, because it would be extremely problematic.
Fork requires cloning of the address space.
The kernel support to do this efficiently is not available
in most non-Unix OSes; e.g. U/win and Cygwin have struggled
to emulate fork under Win32.
In a language such as Java, the garbage collector
& JIT compilers would tend to touch Vmem pages such
that the space would not long remain shared after fork.
Cloning has many side effects.
E.g., input or outputs buffers will be processed in all
of the forked children. SysV shared memory will be detached.
Most languages and many libraries simply refuse to
support forking. This includes the (POSIX) threading API ;
The child is not allowed to use threads until it execs
(i.e., becomes a spawn) !
Perl uses fork because its internals are extremely close to C/Unix,
and its multithreading is abysmal.
Unix shell uses fork by design, which is how it snapshots
all local variables and state. That's also why there is no
decent Unix shell for a non-Unix environment.
In general, I don't believe this is possible in the sense you mean. You can System.exec() to spin off a new process, and can call a new JVM that way. Note that you can certainly call fork() directly from native code, but in the words of a poster here, "Don't. Just don't."

Daemon with Clojure/JVM

I'd like to have a small (not doing too damn much) daemon running on a little server, watching a directory for new files being added to it (and any directories in the main one), and calling another Clojure program to deal with that new file.
Ideally, each file would be added to a queue (a list represented by a ref in Clojure?) and the main process would take care of those files in the queue on a FIFO basis.
My question is: is having a JVM up running this little program all the time too much a resource hog? And do you have any suggestions as to how go about doing this?
Thank you very much!
EDIT: Another question I should ask: should I run this as its own instance (using less memory) and have it launch a new JVM when a file is seen, or have it on the same JVM the Clojure code that will process the file?
As long as it is running fine now and it has no memory leaks it should be fine.
From the daemon terminology I gather it is on a unix clone, and in this case best is to start it from an init script, or from the rc.local script. Unfortunately details differ from OS to OS to be more specific.
Limit the memry using -Xmx=64m or something to make sure it fails before taking down the rest of the services. Play a bit with the number to find the lowest reliable size.
Also, since clojures claim to fame is its ability to deal with concurrency it make a lot of sense to only run one JVM with all functionality running on it in multiple threads. The overhead of spawning new processes is already very big and if it is a JVM which needs to JIT and warm up its memory management, doubly so. On a resource constrained machine could pose a problem. and on a resource rich machine this is a waste.
I always found that the JVM is not made to quickly run something script like and exit again. It is really not made for that use case in my opinion
.