|
|
|
|
|
by gizmo686
783 days ago
|
|
The good thing about this usecase is that they do not need to solve the general problem of forking a multithreades program. The child process is doing a very specific job that amounts to serializing the contents of memory and writing it to a file. Once that is done is can simply exit, and all the orphans are cleaned up. While this is admittadly more complicated, it is the same general idea behind fork+exec. Sure, your serialization logic cannot call malloc, but how often do you really need dynamic memory allocation. And if you really do need to, you can use a simple mmap backed bump allocator (or any other custom allocator you want) For datastructure locks protecting gamestate; just wait until the gamestate is in a consistent state before forking. Of course, if you try reusing existing code, or forget about the limitations while writing new code; it would be easy to introduce non-deterministic bugs. |
|
It is very difficult to write general purpose C++ code that does not call malloc somehere.
Something fails and you want to display a message `"Error: " + reason`? Bam, malloc right here, serialisation process may hang forever in a malloc lock.
You quit the game, the parent process exits, and the serialisation process gets reparented to init, invisibly using up your RAM until you reboot.
fork()+exec() works in C because C has no invisible memory allocation, and even there you'd usually try to not call any function in between the two to be very sure.
Using fork() without being 100% sure there can be no malloc usually means inviting years of rare, hard-to-reproduce random weird bug reports.
Beyond that, as the post mentions, fork() needs "requires a significant amount of RAM to work" if many pages are touched due to copy-on-write, and copy-on-write also slows down the main game.
It seems much safer to use a thread for saving the game state.