John Carmack has some ideas on how to use immutable copies of the game state and functional programming concepts to create something that's easily parallelized. I saw it in an old QuakeCon keynote: https://youtu.be/Uooh0Y9fC_M
In low level audio you have something similar: there's a thread that pulls audio data all the time and it can't stop; at the same time you have potentially lots of things happening in other threads, including the UI one. You can always find ways of minimizing the synchronization overhead by e.g. having a single fast entry point to any changes that happened since the last cycle. With audio you basically end up passing immutable blocks of data with minimal synchronization. So should be possible to do in games, too.
The evolution has been from single threaded engines to different core elements being on seperate threads (e.g. renderer and io) to task based scheduling.
Typically though the updating the game itself is a relatively small part of the frame time and can be reasonably tricky to get real gains through parallelisation.
Audio is a very different problem that is typically about a chain of streaming buffers. The thread pulling audio data (and all the others processing it) is independent from the UI etc., that is not an issue.
Copying and passing immutable data around is not always fast enough and definitely not trivial to merge the results back.
In summary, it is a hard problem with no general solution. If you could solve it, then you have solved multithreading design for any problem.