I'm designing a thread library. So far I have a method that initializes the library, one that creates threads, and one that yields the current thread to the next one on a queue of ready threads.
Before I move on to implementing semaphores for the threads, I figured I should probably kill the threads as soon as they are done and free up their allocated memory, but I'm having trouble figuring out how to do that. How do I tell when a thread has "finished"?
You don't just kill threads safely or reliably -- let them exit naturally (when their entry returns).
Although the system provides a means to kill the thread, nearly any C++ program out there could expect undefined behavior if it were to continue. You could dream up cases where killing could be accomplished without side effects (to the rest of the program), but that program does not at all resemble idiomatic C++. Such a program would be very exotic, with many unusual and severe restrictions.
When you want to known when a thread has exited or not, you can add some cleanup before it exits in order to track its status.
When you want the ability to request a thread exit (naturally), consider run loops and messages.
You don't explicitly kill the threads when they are finished running their forked procedures as the code which would be doing that would still be in the context of the thread to be killed.
You have a scheduler/interrupt handler which handles the context switching of the threads and maintains a few queues for managing this. You can have it save a reference to to the threads to be killed, something like scheduler->SetThreadToKill( currentThread ); inside probably your finish() method (or similar), which sets a flag for the corresponding threads.
When a context switch occurs, and you have swapped out all data structures of the current thread with that of the next thread, you scheduler can call the destructor for all the threads which have the toBeKilled flag set.
The best policy, by far, for killing threads is to not explicitly do it, (unless you are an OS, ie. on app shutdown). Queue messages and tasks to threads that loop around some queue to perform more work. If you don't write any code to continually new, create, start, terminate, delete, test, check, enlist, delist, enqueue, dequeue and otherwise micro-manage threads, then that code cannot contain bugs.
Related
I am working on a c++ project that loads in shared objects and runs a method on them in separate threads. It is a requirement of the system to close down all of these threads after x seconds if they haven’t already terminated. I am able to keep track of which threads have closed but what is the best way to kill one that has not yet finished?
Side Note- Pthread_cancel is causing segmentation faults.
It can't be done. You cannot cancel a thread without its cooperation without risking destroying the process context.
Threads don't provide that kind of isolation. They just don't. If a thread fails, the process fails. You need to contain untrusted or unreliable code in its own process, virtual machine, or the like. Threads are completely permeable.
One of the most common things a thread does is this:
Acquire a lock.
Break some invariants (protected by the lock).
Restore those invariants.
Release the lock.
Now imagine if the thread has completed step 2 but not step 3. You can't release the lock (because that would cause the next thread to acquire the lock to encounter the broken invariants) and you can't leave the lock held (because that would cause the next thread to attempt to acquire the lock to wait forever). So the process context would be destroyed at that point.
You need the thread's cooperation to make it restore the invariants.
I suggest something along the lines suggested here:
Run and break an infinite loop using two threads
In short, set up an exit-condition that your threads are required to check every so often. If it is set, they should return. If all threads should die together, you only need one atomic.
If I terminate a thread on Windows using the TerminateThread function, is that thread actually terminated once the function returns or is termination asychnronous?
Define "actually terminated". The documentation says the thread can not execute any more user-mode code, so effectively: yes, it is terminated, nothing of your code is going to be executed by that thread any more.
If you "WaitForSingleObject" on it right after terminating, I guess there could still be some slight delay because of cleanup that Windows is doing.
By the way: TerminateThread is the worst way of ending a thread. Try using some other means of synchronization, like a global variable that tells the thread to stop, or an event for example.
Terminating a thread is akin to killing a process, only on a per-thread level. It may in fact be implemented by raising an (uncatchable) signal in the targeted thread.
The result is essentially the same: Your program is not in any particular, predictable state. There's not much you can do with the dead thread. The control flow of your program becomes generally indeterminate, and thus it is extremely hard to reason about your program's behaviour in the presence of thread termination.
Basically, unless your thread is doing something extremely narrow, specific and restricted (e.g. increment an atomic counter once every second), there's no good model for the need to terminate a thread, and for the state of the program after the thread termination.
Don't do it. Design your threads so that you can communicate with them and so that their entry functions can return. Design your program so that you can always join all threads eventually and account for everything.
It is a synchronous call. That does not mean that it necessarily returns quickly - there may be some blocking involved if the OS has to resort to using its inter-core driver to stop the thread, (ie. it's actually running on a different core than the thread requesting the termination).
There are issues with calling TerminateThread from user code during an app run, (as distinct from the kernel using it during app/process termination), as clearly posted by others.
I try very hard to never terminate threads at all during an app run, with TerminateThread or by any other means. App-lifetime threads and thread pools often do not require any explicit termination before the OS destroys them on app close.
I'm using CreateThread then TerminateThread to cancel threads. It seems like stack space is still allocated. Is there a way to deal with this? I am not using any form of dynamic memory calls such as malloc/new. Threads do not have to exit gracefully. 10 threads leave behind a whopping 5 MB of memory! The threads are all on varying parts of code, so is there a simple way to implement a interthread communication system which can tell them to all exit gracefully, and therefore reorient the stack?
In most cases you should not use TerminateThread(). If you create new threads in your application, it's your responsibility to make sure that those threads do exit gracefully. When you use TerminateThread(), all kinds of resources may be left behind because this function simply terminates the thread without calling clean-up functions.
TerminateThread documentation
What you should do is use events (or other signaling methods) to tell your threads that they're supposed to shut down. When the thread internally receives the message (the event is signaled or a wait expires, etc.) the thread function can internally clean up and return. This way you'll exit your threads correctly and not leave a mess behind.
A non-auto-reset event and a WaitForMultipleObjects on your primary thread will do what you want. If you find yourself exceeding 64 concurrent worker threads, you'll have to retool to use a different approach, such as non-auto-reset event and a semaphore. There are literally dozens of ways to approach this problem, and countless examples on forums throughout the internet, as well as MS's examples in their distribution of Visual Studio. Start with those.
The deal is:
I want to create a thread that works similarly to executing a new .exe in Windows, so if that program (new thread) crashes or goes into infinite loop: it will be killed gracefully (after the time limit exceeded or when it crashed) and all resources freed properly.
And when that thread has succeeded, i would like to be able to modify some global variable which could have some data in it, such as a list of files for example. That is why i cant just execute external executable from Windows, since i cant access the variables inside the function that got executed into the new thread.
Edit: Clarified the problem a lot more.
The thread will already run after calling CreateThread.
WaitForSingleObject is not necessary (unless you really want to wait for the thread to finish); but it will not "force-quit" the thread; in fact, force-quitting - even if it might be possible - is never such a good idea; you might e.g. leave resources opened or otherwise leave your application in a state which is no good.
A thread is not some sort of magical object that can be made to do things. It is a separate path of execution through your code. Your code cannot be made to jump arbitrarily around its codebase unless you specifically program it to do so. And even then, it can only be done within the rules of C++ (ie: calling functions).
You cannot kill a thread because killing a thread would utterly wreck some of the most fundamental assumptions a programmer makes. You would now have to take into account the possibility that the next line doesn't execute for reasons that you can neither predict nor prevent.
This isn't like exception handling, where C++ specifically requires destructors to be called, and you have the ability to catch exceptions and do special cleanup. You're talking about executing one piece of code, then suddenly ending the execution of that entire call-stack. That's not going to work.
The reason that web browsers moved from a "thread-per-tab" to "process-per-tab" model is exactly this: because processes can be terminated without leaving the other processes in an unknown state. What you need is to use processes instead of threads.
When the process finishes and sets it's data, you need to use some inter-process communication system to read that data (I like Boost.Interprocess myself). It won't look like a regular C++ global variable, but you shouldn't have a problem with reading it. This way, you can effectively kill the process if it's taking too long, and your program will remain in a reasonable state.
Well, that's what WaitForSingleObject does. It blocks until the object does something (in case of a thread it waits until the thread exits or the timeout elapses). What you need is
HANDLE thread = CreateThread(0, 0, do_stuff, NULL, 0, 0);
//rest of code that will run paralelly with your new thread.
WaitForSingleObject(thread, 4000); // wait 4 seconds or for the other thread to exit
If you want your worker thread to shut down after a period of time has elapsed, the best way to do that is to have the thread itself monitor the elapsed time in some way and then exit when the time is up.
Another way to do this is to monitor the elapsed time in the main thread or even a third, monitor type thread. When the time has elapsed, set an event. Your worker thread could wait for this event in it's main loop, and then exit when it has been raised. These kinds of events, which are used to signal the thread to kill itself, are sometimes called "death events." (Or at least, I call them that.)
Yet another way to do this is to queue a user job to the worker thread, which needs to be in an alterable wait state. The APC can then set some internal state variable which will trigger the death sequence in the thread when it resumes.
There is another method which I hesitate even mentioning, because it should only be used in extremely dire circumstances. You can kill the thread. This is a very dangerous method akin to turning off your sink by detonating an atomic bomb. You get the sink turned off, but there could be other unintended consequences as well. Please don't do this unless you know exactly what you're doing and why.
Remove the call to WaitForSingleObject. That causes your parent thread to wait.
Remove the WaitForSingleObject call?
so I have some main function. 24 time a second it opens a boost thread A with a function. that function takes in a buffer with data. It starts up a boost timer. It opens another thread B with a function sending buffer into it. I need thread A to kill thread B if it is executing way 2 long. Of course if thread B has executed in time I do not need to kill it it should kill itself. What boost function can help me to kill created thread (not join - stop/kill or something like that)?
BTW I cannot affect speed of Function I am exequting in thread B thats why I need to be capable of killing it when needed.
There's no clean way to kill a thread, so if you need to do something like this, your clean choices are to either use a function that includes some cancellation capability, or use a separate process for it, since you can kill a process cleanly.
Other than that, my immediate reaction is that instead of "opening" (do you mean creating?) thread A 24 times a second, you'd be better off with thread A reading a buffer, sending it on to thread B, then sleeping until it's ready to read another buffer. Creating and killing threads isn't terribly expensive, but doing it at a rate of 24 (or, apparently, 48) a second strikes me as a bit excessive.
The term you are looking for is "cancellation", as in pthread_cancel(3). Cancellation is troublesome, because the cancelled thread might not execute C++ destructors or release locks on the way out ... but then again it might; the uncertainty is actually worse than a definitive no.
Because of this, boost threads do not support cancellation (see for instance this older question) but they do support interruption, which you might be able to bend to fit. Interruption works by way of a regular C++ exception so it has predictable semantics.
please don't kill threads at random unless you completely control their execution (and then just make proper signals for threads to exit gracefully). you never know if other thread is in some critical section of a library you never heard of and then your program will end up stalling on that CS as it was never exited or something like that.