Is combining multithreading and multiprocessing useful?
Yes. An example is the popular node.js JavaScript engine.
It supports a single thread for JavaScript code per process, but uses multithreading to perform I/O (and other tasks). In order to use multiple CPUs/cores, it needs to spawn multiple processes, each having its own pool of threads for I/O.
You can observe this by running the cluster.mjs example application that starts as many node.js processes as there are CPUs, and then starts 10 threads in each process. The initial node.js process serves as the coordinator.
Here's the output of pstree
on a 64-processor machine:
node─┬─node─┬─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ └─{node}
├─node─┬─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ └─{node}
... repeats number of CPU times ...
├─node─┬─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ ├─{node}
│ └─{node}
├─{node}
├─{node}
├─{node}
├─{node}
├─{node}
├─{node}
├─{node}
├─{node}
├─{node}
└─{node}