Mechanism of join() in multithreading - multithreading

I was studying about multi-threading and came across join().
As I understand right, using join() on the thread makes process wait until 'joined' thread terminates. For example, calling t1.join() in main will make main wait until the job in thread t1 is finished and t1 terminates.
I'm just curious that how the function join() make this possible - how does it make current thread 'blocked' inside the function? Does join() force execution of joined thread first so any other thread should wait until that thread terminates? Or, is there some way to communicate between two threads(the thread who called join() and the thread who is joined)?
I will be waiting for the answer. Thanks a lot!

To be able to join you need to be able to wait on some event. Then join looks like this:
function join(t : Thread)
// do this atomically
if already done
return
wait on termination event of t
end
Waiting can be done in one of two ways:
Looping and periodically checking if the event has happened (busy wait)
Letting the system reclaim the resources of the thread and be woken up on a system event, in that case waking the thread is managed by the scheduler of the OS

It's rather language specific.
Once you create a thread, it starts running.
A join operation is when your main process stops and waits for the thread to exit and capture a return code. It will block until your thread completes - that's rather the point, as it allows for a synchronization to occur - everything in your program is at a 'known state'.
Related is the detach operation, which is effectively saying 'I don't care any more'.

Related

Waiting std::condition_variable while forking and forked child process is unable to resume it

I am trying to understand forking with multithreading. So what happens in below scenario ?
Application thread has spawned a thread - polling thread
Application thread runs fork
atpthread_fork handler's pre_fork stops the polling thread using a std::condition_variable. It also waits on a different condition variable to resume the polling
atpthread_fork handler's post_fork in child does cv.notify_one for the waiting poll thread and stops the poll thread
atpthread_fork handler's post_fork in parent does cv.notify_one for the waiting poll thread and resumes the poll thread
But what happens is, post_fork in child enters an infinite loop where it keeps on waiting. This also doesn't seem to notified the poll thread cv at all.
Why is this happening ?
I am trying to understand forking with multithreading.
The #1 thing to understand about combining forking with multithreading is don't do it. The combination is highly problematic other than in a handful of special cases.
So what happens in below scenario ?
Application thread has spawned a thread - polling thread
Application thread runs fork
atpthread_fork handler's pre_fork stops the polling thread using a std::condition_variable. It also waits on a different condition
variable to resume the polling
That makes no sense. A condition variable does not have the power to preemptively make any thread stop. And if the polling thread eventually did stop by blocking on the CV, then what role would a different CV have to play in starting it again?
atpthread_fork handler's post_fork in child does cv.notify_one for the waiting poll thread and stops the poll thread
I suppose you meant to say that a post_fork handler registered via pthread_atfork performs a cv.notify_one in the child to resume the poll thread.
Any way around, it is impossible for the child to do anything with the polling thread because it doesn't have one. The child process has only one thread -- a copy of the one that called fork(). This is one of the main reasons why forking and multithreading don't mix.
atpthread_fork handler's post_fork in parent does cv.notify_one for the waiting poll thread and resumes the poll thread
This seems questionable in light of the overall questionable behavior you are attributing to the CVs, but there is nothing inherently wrong with the concept.
But what happens is, post_fork in child enters an infinite loop where
it keeps on waiting.
Something is missing here. Are you doing a timed wait? Is its wait failing? These are the only ways I can think of that the child could be both looping and waiting. There is initially no other thread in the child process to wake the single one that resulted from the fork, so that thread cannot perform a successful return from a wait on any CV, unless spurriously. There is no one to signal it.
This also doesn't seem to notified the poll
thread cv at all.
Do you mean the one in the child that doesn't exist? Or the one in the parent that probably isn't waiting on the CV you think it's waiting on?
Most of the above is moot. There is absolutely no reason to think that your program is exercising one of the special exceptions, so refer to #1: don't combine forking with multithreading. Choose one.

Thread deletion design

I have multi thread program. I have a design of my application as follows:
Suppose one is main thread, and other are slave threads. Main thread keep track of all slave thread ID's. During one of the scenario of application (one of the scenario is graceful shutdown of application), i want to delete slave threads from main thread.
Here slave threads may be executing i.e., either in sleep mode or doing some action which i cannot stop the action. So i want to delete the threads from main thread with thread IDs i stored internally.
Additional info:
While deleting i should not wait for thread current action to complete as it may take long time as i am reading from data base and taking some action in thread, in case of gracefull shut down i should not wait for action to complete as it may take time.
If i force delete a thread how can there will be a resource leaks?
Is above design is ok or there is any flow or any ways we can improve the design.
Thanks!
It's not okay. It's a bad practice to forcefully kill a thread from another thread because you'll very likely to have resource leaks. The best way is to use an event or signal to signal the client process to stop and wait until they exit gracefully.
The overall flow of the program would look like this:
Parent thread creates an event (say hEventParent). it then creates child threads and passes hEventParent as a parameter. The Parent thread keeps the hThread of the child thread(s).
Child threads do work but periodically waits for hEventParent.
When the program needs to exit, the parent thread sets hEventParent. It then waits for hThread (WaitForMultipleObjects also accepts hThread)
Child thread is notified then execute clean up routine and exits.
When all the threads exit, the parent can then exit.
The most common approach consists in the main thread sending a termination signal to all the threads, then waiting for the threads to end.
Typically the worker threads will have a loop, inside of which the work is done. You can add a boolean variable that indicates if the thread needs to end. For example:
terminate = false;
while (!terminate) {
// work here
}
If you want your worker threads to go to sleep when they have no work, then it gets a bit more complicated. In this case you could make the threads wait on semaphores. Each semaphore will be signaled when there is work to do, and that will awaken the thread. You will also signal the semaphore when the request to terminate is issued. Example worker thread:
terminate = false;
while (!terminate) {
// work here
wait(semaphore); // go to sleep
}
When the main thread wants to exit it will set terminate to true for all the threads and then signal the thread semaphores to awaken the threads and give them a chance to see the termination request. After that it will join all the threads, and only after all the threads are finished it will exit.
Note that the terminate boolean may need to be declared as volatile if you are using C/C++, to indicate to the compiler that it may be changed from another thread.

synchronising threads with mutexes

In Qt, I have a method which contains a mutex lock and unlock. The problem is when the mutex is unlock it sometimes take long before the other thread gets the lock back. In other words it seems the same thread can get the lock back(method called in a loop) even though another thread is waiting for it. What can I do about this? One thread is a qthread and the other thread is the main thread.
You can have your thread that just unlocked the mutex relinquish the processor. On Posix, you do that by calling pthread_yield() and on Windows by calling Sleep(0).
That said, there is no guarantee that the thread waiting on the lock will be scheduled before your thread wakes up again.
It shouldn't be possible to release a lock and then get it back if some other thread is already waiting on it.
Check that you actually releasing the lock when you think you do. Check that waiting thread actually waits (and not spins a loop with a trylock tests and sleeps, I actually done that once and was very puzzled at first :)).
Or if waiting thread really never gets time to even reach locking code, try QThread::yieldCurrentThread(). This will stop current thread and give scheduler a chance to give execution to somebody else. Might cause unnecessary switching depending on tightness of your loop.
If you want to make sure that one thread has priority over the other ones, an option is to use a QReadWriteLock. It's adapted to a typical scenario where n threads are going to read a value in a infinite loop, with only one thread updating it. I think it's the scenario you described.
QReadWriteLock offers two ways to lock: lockForRead() and lockForWrite(). The threads depending on the value will use the latter, while the thread updating the value (typically via the GUI) will use the former (lockForWrite()) and will have top priority. You won't need to sleep or yield or whatever.
Example code
Let's say you have a QReadWrite lock; somewhere.
"Reader" thread
forever {
lock.lockForRead();
if (condition) {
do_stuff();
}
lock.unlock();
}
"Writer" thread
// external input (eg. user) changes the thread
lock.lockForWrite(); // will block as soon as the reader lock ends
update_condition();
lock.unlock();

How to do asynchronous inter thread communication on platform with pthreads

For example on windows there is MsgWaitForMultipleObjects that lets you asynchronously wait for windows messages, socket events, asynchronous io (IOCompletionRoutine), AND mutex handles.
On Unix you have select/poll that gives you everything except possibility to break out when some pthread_mutex is unlocked.
The story:
I have application that has main thread that does something with multiple sockets, pipes or files. Now from time to time there is a side job (a db transaction) that might take a longer time and if done synchronously in main thread would disrupt normal servicing of sockets. So I want to do the db operation in separate thread. That thread would wait on some mutex when idle until main thread decides to give it some job and unlocks the mutex so db thread can grab it.
The problem is how the db thread can notify back the main thread that it has finished the job. Main thread has to process sockets, so it cannot afford sleeping in pthread_mutex_lock. Doing periodic pthread_mutex_trylock is the last I would want to do. Currently I consider using a pipe, but is this the better way?
Using a pipe is a good idea here. Make sure that no other process has the write end of the pipe open, and then select() or poll() in the main thread the read end for reading. Once your worker thread is done with the work, close() the write end. The select() in the main thread wakes up immediately.
I don't think waiting on a mutex and something else would be possible, because on Linux, mutexes are implemented with the futex(2) system call, which doesn't support file descriptors.
I don't know how well it applies to your specific problem, but posix has message queues.

Tell if 'elapsed' event thread is still running?

Given a System.Timers.Timer, is there a way from the main thread to tell if the worker thread running the elapsed event code is still running?
In other words, how can one make sure the code running in the worker thread is not currently running before stopping the timer or the main app/service thread the timer is running in?
Is this a matter of ditching Timer for threading timer using state, or is it just time to use threads directly?
Look up ManualResetEvent, as it is made to do specifically what you're asking for.
Your threads create a new reset event, and add it to an accessible queue that your main thread can use to see if any threads are still running.
// main thread owns this
private List<ManualResetEvent> _resetEvents;
...
// main thread does this to wait for executing threads to finish
WaitHandle.WaitAll(_resetEvents.ToArray(), 2000, false)
...
// worker threads do this to signal the thread is done
myResetEvent.Set();
I can give you more sample code if you want, but I basically just copied it from the couple articles I read when I had to do this a year ago or so.
Forgot to mention, you can't add this functionality to the default threads you'll get when your timer fires. So you should make your timer handler be very lean and do nothing more than prepare and start a new worker thread.
...
ThreadPool.QueueUserWorkItem(new WaitCallback(MyWorkerDelegate),
myCustomObjectThatContainsAResetEvent);
For the out of the box solution, there is no way. The main reason is the thread running the TimerCallback function is in all likelihood still alive even if the code running the callback has completed. The TimerCallback is executed by a Thread out of the ThreadPool. When the task is completed the thread does not die, but instead goes back into the queue for the next thread pool task.
In order to get this to work your going to have to use a manner of thread safe signalling to detect the operation has completed.
Timer Documentation

Resources