Choice between multithreading and multi-processing: When to use what