threads will join in their destructor, which means the thread object must remain alive for as long as you want the thread open.
So making it local in an if() block is bad, because it goes out of scope as soon as the if() ends, which means the thread also ends.
You'll have to keep these threads at a larger scope.
1 2 3 4 5 6 7 8 9 10 11 12
// perhaps as a member of XControl?
typedef std::unique_ptr< std::thread > threadptr;
std::vector< threadptr > openThreads;
// then when you want to make threads...
openThreads.push_back( threadptr( new std::thread(&XControl::ControlThread,this,slot) ) );