I think there is a time and a place for everything. I use concurrent.futures in certain situations when I need to utilize threads/procs to do work in a very rudimentary and naive way. But in more sophisticated systems you want to control startup/shutdown of a process.
TBH, assuming your stack allows it, gevent is my preferred mechanism for concurrency in Python. Followed by asyncio.
For places where I really need to get my hands dirty I will lean on manually controlling processes/threads.