Threads are typically not the way to take advantage of multiple CPUs for CPU-bound problems. The Global Interpreter Lock (GIL) allows the use of only one CPU at the time when using threads. However, the GIL is released for IO task.
The use case is a scientific simulation model that has to run 18,000 different simulations. The input data for these simulations need to be extracted from a common database, re-assembled and translated into several input files per simulation. After each simulation that is run with an external, standalone executable, the output data needs to be gathered and rearranged in a output database.
The implementation scaled up to 50 threads. On a eight-core machine more than 90 % usage of all CPUs could be achieved, bringing the total run time down to about two hours from about 15 hours.
Depending on the use case, threading can help to speedup a program and even take advantage of multiple CPUs. This talk presents such a use case. The approach can be translated to problems from other domains if the sub-tasks can be turned into IO tasks.
Asynchronous programming could have been used here. However using a thread per task and using class that represents a task, is likely conceptually simpler for programmers not used to asynchronous programming.