Shared mutable state is where the problem lies, but in a lot of cases shared memory can be used to pass it without copying from a "scheduler" thread to worker threads for parallel processing in non-overlapping chunks, and then back for compiling into a whole.
They manage without threads pretty well, I think. Shared state is deliberate, outside of individual processes, rather than accidental in-process. As it should be unless you are doing some serious systems level programming.
Actor model with messages (events) sent between potentially isolated processes, perhaps?
If you truly need to run a compute intensive task in the background, the effort to [de]serialize a “command object” to and from another process should not be much overhead, vs sharing almost all memory by default.
Once you reach the point where you are starting a thread pool at start up, rather than spawning threads on demand, why not just have a process pool?
Shared memory blocks can also be used to explicitly share data too large to effectively serialize as a message / event.
If you truly have something that pumps huge amounts of data between compute intensive tasks, then threads make sense. Proceed with extreme caution, and try to encapsulate the trick bits.
I.e. does it allow passing large parts of data structures without copying?
This is the case much more often now than it was in 1995.