Most thread communication can be handled using one of the synchronization primitives like a mutex, event, semaphore, monitor, etc.
You could also set a flag variable in the main thread in shared storage that the thread could then check to see if it should exit or not.