The problem with forcefully stopping a thread is that no cleanup procedure is executed, so any created objects, opened files, acquired locks, or generally allocated resources will not be freed.
Therefore checking for a termination flag is usually the best practice. That said, if you can't redesign your code around that (maybe you call blocking library code or similar you just cant avoid) there is another way, using signals.
You must register a signal handler, which will perform cleanup and then forcefully kill the thread. For this to work, all acquired resources must be accessible from the handler, meaning no local variables that reference shared resources (class instances, files, heap pointer, etc). No managed types (strings, arrays) should anywhere in that thread. When accessing the shared objects, lock these operations by masking out the signal, but keep these locks as small as possible, othereise you cant force terminate.
If you can do that, this will be fine. That said, code that does not contain strings, arrays or temporary classes is probably not that useful