Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

That's quite a copout with forkall. Presumably you have some idea what your threads are doing if you want to fork the entire process, so don't do it in the middle of writing to a file.


How many libraries do you use? Are you sure they don't create their own threads?

Also, just imagine something like this:

    file.write(blah);
    if (has_forked) thread_exit();
    file.write(blah2);
    if (has_forked) thread_exit();
    file.write(blah3)
    if (has_forked) thread_exit();
Note the race conditions in the above code... forkall() is a disaster. Presumably you'd combine it with pthread_atfork(), but it's still a total mess.


How could you know what your threads are doing at the time you call fork? That doesn't sound safe. I write such code in a way that threads communicate with each other when they need to, but if I start assuming what those threads are doing that seems like it could get really complicated really fast.


Sure it can get complicated, but there are also some safe ways to fork. Imagine you fork at the very beginning of your program before starting any threads. No danger in that. So the language could at least allow it (but provide the proper warnings around it).


the issue arises when the programming language doesn't let you run code before the threads split out, like golang.


I don't know exactly what they're doing, but being able to reason that they are not performing file IO is a vastly easier problem than figuring out a completely safe point to kill them all.


Does forkall exist on Linux? I was under the impression it's a nonstandard Solaris extension.


That's a much better reason. But such a problem isn't set in stone.


I've always thought fork() was a hack anyway. 99% of the time, fork() is followed by a call to an exec() variant. The actual process forking behavior seems useful in only a small set of cases that could be handled by spawning a process and passing state explicitly. The benefits of fork() don't seem to offset its costs or justify its widespread use.

fork() is one of those things that's conceptually quite elegant but in practice has too many problematic edge cases. (Signals seem to fall into the same group.)


Spawning a process by passing state explicitly is what Windows does. The CreateProcess call takes 10 parameters, several of which are structures containing even more parameters - http://msdn.microsoft.com/en-us/library/windows/desktop/ms68...

I do like that fork, then setup functions, then exec keeps the code simpler. If everything is done as a single call like CreateProcess then it needs to have a way of passing what the setup functions need as data - rather a lot of it.


That's conflating separate issues. Windows could have a CreateProcessSimple() call that spawns a new process without so many options. CreateProcess is complex not so much because it is one call instead of two, but because it has all options jumbled together.

Meanwhile the Linux/Unix decision was to have about a dozen different APIs to do variants of the same thing (fork, vfork, and clone plus execl, execlp, execle, execv, execvp, execvpe, fexecve, posix_spawn, posix_spawnp, and probably more). This isn't really any less complex.

The argument complexity of CreateProcess could not possibly derive from merging fork() and exec() because fork() has no arguments.


CreateProcess is complex because spawning a new process is essentially complex.

The brilliance of fork/exec is in the realization that the tasks you do during process creation are the same as the tasks you do during normal execution, and therefore you can just re-use those functions. For example, CreateProcess has a parameter for the current directory; fork/exec doesn't need one because you just use chdir on the child side of fork.

The proliferation of exec* is indeed baffling, but these are just dumb variants trying to make the exec call itself "easier." They don't reflect any essential complexity.


It's not enough to merge fork() and execve(), because what actually happens is some variant of:

fork(); open(); close(); dup2(); fdcntl(); sigprocmask(); sigaction(); setrlimit(); prctl(); chdir(); chroot(); capset(); execve();

(and perhaps more besides, with new ones potentially added with new features, for example seccomp();)


That seems like compelling evidence that the Linux method is more complex than the Windows method (or at least no less complex). Calling a bunch of complex functions is not simpler than setting up a bunch of complex params and then calling one function.


Approximately zero programs will call all of those functions, but each will call its own required subset of them. If you don't care about running the child with an altered root directory, you don't need to call chroot().


Of course. Most programs also don't need all the esoteric options that can be passed into CreateProcess either.


I don't think anyone who's thought about it for a moment disagrees that starting a process has a large degree of potential complexity, regardless of the operating system.

The question is whether it's better (more elegant) to load that complexity onto one complex function call, or farm it out to multiple simple function calls. It is apparent that this is a question in which personal taste is involved.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: