This could be a non programming question to all,i did read about the thread synchronization objects such as event and how it is set as signalled or non-signalled state . However i couldn't understand these terms signalled and non-signalled .Each one has expressed in different ways and i'm bit confused.
This link states that
A signaled state indicates a resource is available for a process or thread to use it. A not-signaled state indicates the resource is in use.
I got an power point presentation from an university site which states that
An object that is in the signaled state will not cause a thread that is waiting on the object to block and object that is not in the signaled state will cause any thread that waits on that object to block until the object again becomes signaled.
This third link states this
An event is in signaled state means that it has the capacity to release the threads waiting for this event to be signaled. An event is in non signaled state means that it will not release any thread that is waiting for this particular event.
A simple explanation on this concept with an example would be really helpful.
Ok, your 3 quotes are not incompatible. But let's go a bit down to the implementation:
Every waitable object has a boolean value attached to it, named the signalled state, that is used to wait for that object; if the object is signalled, then the wait functions will not wait for it; if the object is non-signalled, then the wait functions will wait for it.
Now, how does this apply to a particular type of object? That depends on the objects nature and specifically on the semantics associated to waiting for it. Actually, the signalled state is defined in terms of wait condition. the For example (see the docs for details):
A mutex is signalled when it is not owned.
An process/thread is signalled when it has finished.
A semaphore is signalled when its count is greater than 0.
A waitable timer is signalled when it has expired.
You might like better if a mutex were signalled when owned, but actually it is when not owned. That's necessary to make the wait functions do the right thing.
And what about the events? Well, they are somewhat simple objects, you can signal and de-signal them at will, so the signal state has no additional meaning:
signalled: Threads will not wait for it.
non-signalled: Threads will wait for it.
Events also have this SignalPulse and AutoReset things that are a bit peculiar (and IME practically impossible to use right).
Now, let's look at your quotes:
A signaled state indicates a resource is available for a process or thread to use it. A not-signaled state indicates the resource is in use.
Actually, that is an interpretation. Usually there is a resource you are trying to arbitrate, and usually you wait if-and-only-if that resource is in use, so it is making the equivalence between resource-in-use and wait-for-resource. But that's not a technical requiremente, just a usual use-case.
An object that is in the signaled state will not cause a thread that is waiting on the object to block and object that is not in the signaled state will cause any thread that waits on that object to block until the object again becomes signaled.
Correct and to the point!
An event is in signaled state means that it has the capacity to release the threads waiting for this event to be signaled. An event is in non signaled state means that it will not release any thread that is waiting for this particular event.
I find this wording a bit confusing... but it adds nothing over the previous one.
Easy way to think of it: "signalled" = "green light"
Signalled:
If you're driving and you see a green light you don't stop (this is the thread looking at an event, finding it's signalled and carrying on without blocking).
Non-Signalled:
If you see a red light you stop and wait for it to become green and then carry on (safe in the knowledge the other threads all are now non-signalled thus are waiting or will wait at their...red light!)
Well, in fact all these explainations are congruent.
The most simplified (and hence not 100% accurate) explaination of an event is to see an event as kind of a flag service provided by the operating system. A signaled Event can be seen as a set flag, an unsignalled event on the other hand can be seen as an unset flag.
For implementing a producer/consumer thread-system based on flags, you usually do something like the following (note for the sake of simplicity i neglect further synchronization mechanisms):
static volatile int flag = 0;
static volatile char data = 'A';
// Some code to initialize the threads
void producer()
{
while (1)
{
Sleep(1000);
data++;
flag = 1;
}
}
void consumer()
{
while (1)
{
/* Busy wait for the occurence of more data */
while (!flag)
{
// wait for next data
}
flag = 0;
// process data
}
}
Unluckily this would lead to a waste of processor cycles in the busy wait loop or unwanted deferral of execution due to a Sleep call introduced to lower the CPU consumption. Both is unwanted.
In order to avoid such problems with task synchronization, operating systems provide different flag like mechanisms (e.g. Events in Windows). With events, setting and resetting a flag is done by the OS calls SetEvent/ResetEvent. To check for a flag you can use WaitForSingleObject. This call has the power to put a task to sleep until the event is signalled which is optimal in terms of CPU consumption.
This turns the above example into something like this:
static volatile char data = 'A';
static HANDLE newDataEvent = INVALID_HANDLE_VALUE;
// Some code to initialize the threads and the newDataEvent handle
void producer()
{
while (1)
{
Sleep(1000);
data++;
SetEvent(newDataEvent);
}
}
void consumer()
{
while (1)
{
if (WaitForSingleObject(newDataEvent, INFINITE) == WAIT_OBJECT_0)
{
ResetEvent(newDataEvent);
// process data
}
}
}
I don't really agree with other answers. They miss the point:
if signaled property is true => the event happened before now.
if signaled property is false => the event did not happened until now.
Where "signal property is false" equals to "not-signal property is true".
And the three definition all refers to threads but they are not clear because signal definition doesn't come from multi-threading but from low level programming .
Signals comes from interrupts:
"if that signal becomes high(=interrupt) move the execution pointer to this function".
This is the meaning of signal, and it comes from interrupts not from threading. And so, not-signaled means, the signal didn't become high until now.
In threading this become:
"A thread needs that an event is happened to continue. If it's happend before now, it can continue; otherwise it blocks itself and wait for it."
Related
The ASIO documentation for basic_deadline_timer::cancel() has the following remarks section:
If the timer has already expired when cancel() is called, then the handlers for asynchronous wait operations will:
have already been invoked; or
have been queued for invocation in the near future.
These handlers can no longer be cancelled, and therefore are passed an error code that indicates the successful completion of the wait operation.
The emphasis has been added by me. Normally when you call cancel() on a timer, the callback is run with an error code of "operation cancelled by user". But this says there is a small chance it could actually be called with a success error code. I think it is trying to say that the following could happen:
Thread A calls async_wait(myTimerHandler) on a timer, where myTimerHandler() is a user callback function.
Thread B calls io_context::post(cancelMyTimer) where cancelMyTimer() is a user callback function. This is now queued up to be called in thread A.
The timer deadline expires, so ASIO queues up the timer callback handler, with a success error code. It doesn't call it yet, but it is queued up to be called in thread A.
ASIO gets round to calling cancelMyTimer() in thread A, which calls cancel() on the timer. But the timer already fired, and ASIO doesn't check that the handler is still queued up and not executed, so this does nothing.
ASIO now calls myTimerHandler, and doesn't check that cancel() was called in the meantime, and so it still passes success as the error code.
Bear in mind this example only has a single thread calling io_context::run(), deadline_timer::async_wait or deadline_timer::cancel(). The only thing that happened in another thread was a call to post(), which happened in an attempt to avoid any race conditions. Is this sequence of events possible? Or is it referring to some multithreading scenario (that seems unlikely given that timers are not thread safe)?
Context: If you have a timer that you wish to repeat periodically, then the obvious thing to do is check the error code in the callback, and set the timer again if the code is success. If the above race is possible, then it would be necessary to have a separate variable saying whether you cancelled the timer, which you update in addition to calling cancel().
You don't even need a second thread to run into a situation where basic_waitable_timer::cancel() is invoked too late (because the timer's (completion) handler is already queued).
It's sufficient that your program executes some other asynchronous operations concurrently to the not yet resumed basic_waitable_timer::async_wait(). If you then only rely on basic_waitable_timer::cancel() for cancellation then the cancel() call from another asynchronous (completion) handler races with an already scheduled async_wait() handler:
If the timer has already expired when cancel() is called, then the handlers for asynchronous wait operations will:
have already been invoked; or
have been queued for invocation in the near future.
These handlers can no longer be cancelled, and therefore are passed an error code that indicates the successful completion of the wait operation.
(basic_waitable_timer::cancel(), emphasis mine, i.e. the race condition is due to the second case)
A real-world example that is single-threaded (i.e. the program doesn't explicitly start any threads and only invokes io_server.run() once) and contains the described race:
void Fetch_Timer::resume()
{
timer_.expires_from_now(std::chrono::seconds(1));
timer_.async_wait([this](const boost::system::error_code &ec)
{
BOOST_LOG_FUNCTION();
if (ec) {
if (ec.value() == boost::asio::error::operation_aborted)
return;
THROW_ERROR(ec);
} else {
print();
resume();
}
});
}
void Fetch_Timer::stop()
{
print();
timer_.cancel();
}
(Source: imapdl/copy/fetch_timer.cc)
In this example, the obvious fix (i.e. also querying a boolean flag) doesn't even need to use any synchronization primitives (such as atomics), because the program is single-threaded. That means it executes (asynchronous) operations concurrently but not in parallel.
(FWIW, in the above example, the bug manifested itself only every 2 years or so, even under daily usage)
Everything you stated is correct. So in your situation you could need a separate variable to indicate you don’t want to continue the loop. I normally used a atomic_bool and I don’t bother posting a cancel routine, I just set the bool & call cancel from whatever thread I am on.
UPDATE:
The source for my answer is mainly experience in using ASIO for years and for understanding the asio codebase enough to fix problems and extend parts of it when required.
Yes the documentation says that the it's not thread safe between shared instances of the deadline_timer, but the documentation is not the best (what documentation is...). If you look at the source for how the "cancel" works we can see:
Boost Asio version 1.69: boost\asio\detail\impl\win_iocp_io_context.hpp
template <typename Time_Traits>
std::size_t win_iocp_io_context::cancel_timer(timer_queue<Time_Traits>& queue,
typename timer_queue<Time_Traits>::per_timer_data& timer,
std::size_t max_cancelled)
{
// If the service has been shut down we silently ignore the cancellation.
if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
return 0;
mutex::scoped_lock lock(dispatch_mutex_);
op_queue<win_iocp_operation> ops;
std::size_t n = queue.cancel_timer(timer, ops, max_cancelled);
post_deferred_completions(ops);
return n;
}
You can see that the cancel operation is guarded by a mutex lock so the "cancel" operation is thread safe.
Calling most of the other operations on deadline timer is not (in regards to calling them at the same time from multiple threads).
Also I think you are correct about the restarting of timers in quick order. I don't normally have a use case for stopping and starting timers in that sort of fashion, so I've never needed to do that.
This really is two questions, but I suppose it's better they be combined.
We're working on a client that uses asynchronous TCP connection. The idea is that the program will block until certain message is received from the server, which will invoke a SIGPOLL handler. We are using a busy waiting loop, basically:
var = 1
while (var) usleep(100);
//...and somewhere else
void sigpoll_handler(int signum){
......
var = 0;
......
}
We would like to use something more reliable instead, like a semaphore. The thing is, when a thread is blocked on a semaphore, will the signal get through still? Especially considering that signals get delivered when it switches back to user level; if the process is off the runqueue, how will it happen?
Side question (just out of curiosity):
Without the "usleep(100)" the program never progresses past the while loop, although I can verify the variable was set in the handler. Why is that? Printing changes its behaviour too.
Cheers!
[too long for a comment]
Accessing var from inside the signal handler invokes undefined behaviour (at least for a POSIX conforming system).
From the related POSIX specification:
[...] if the process is single-threaded and a signal handler is executed [...] the behavior is undefined if the signal handler refers to any object [...] with static storage duration other than by assigning a value to an object declared as volatile sig_atomic_t [...]
So var shall be defined:
volatile sig_atomic_t var;
The busy waiting while-loop, can be replaced by a single call to a blocking pause(), as it will return on reception of the signal.
From the related POSIX specification:
The pause() function shall suspend the calling thread until delivery of a signal whose action is either to execute a signal-catching function or to terminate the process.
Using pause(), btw, will make the use of any global flag like var redundant, to not say needless.
Short answer: yes, the signal will get through fine with a good implementation.
If you're going to be using a semaphore to control the flow of the program, you'll want to have the listening be on one child with the actual data processing be on another. This will then put the concurrency fairness in the hands of the OS which will make sure your signal listening thread gets a chance to check for a signal with some regularity. It shouldn't ever be really "off the runqueue," but cycling through positions on the runqueue instead.
If it helps you to think about it, what you have right now seems to basically be a a very rough implementation of a semaphore on its own -- a shared variable whose value will stop one block of code from executing until another code block clears it. There isn't anything inherently paralyzing about a semaphore on a system level.
I kind of wonder why whatever function you're using to listen for the SIGPOLL isn't doing its own blocking, though. Most of those utilities that I've seen will stop their calling thread until they return a value. Basically they handle the concurrency for you and you can code as if you were dealing with a normal synchronous program.
With regards to the usleep loop: I'd have to look at what the optimizer's doing, but I think there are basically two possibilities. I think it's unlikely, but it could be that the no-body loop is compiling into something that isn't actually checking for a value change and is instead just looping. More likely to me would be that the lack of any body steps is messing up the underlying concurrency handling, and the loop is executing so quickly that nothing else is getting a chance to run -- the queue is being flooded by loop iterations and your signal processsing can't get a word in edgewise. You could try just watching it for a few hours to see if anything changes; theoretically if it's just a concurrency problem then the random factor involved could clear the block on its own with a few billion chances.
I'm trying to start a thread as soon as an interrupt occurs. However, I have realized that I can't start a thread from within an interrupt handler (or any function that is directly or indirectly being called by the interrupt handler). So, what I have decided to do is have the handler assert a flag. Then, a separate thread continously monitors that flag and if it's asserted it will in turn create (and start) a thread. Here's a pseudocode:
int interrupt_flag = 0;
interrupt_handler(void)
{
interrupt_flag = 1
}
monitoring_thread(void) //this thread is started at the start of the program
{
while(1)
{
if(interrupt_flag)
{
interrupt_flag = 0;
//start the thread here
sleep(/*some amount of time*/);
}
}
}
I'm not really happy with having a dedicated while loop constantly monitoring a flag. The problem with this is that it significantly reduces the speed of the other threads in my program. For this reason, I'm calling the sleep function to increase the speed of the other threads in my program.
Question: Is there a way I can truly start a thread upon interrupt, without having a dedicated while loop? Is there a workaround for starting a thread from within an interrupt handler?
If it makes any difference, I'm using the POSIX library.
Thanks,
PS. This question is somewhat related to an earlier question posted here:
Sharing data between master thread and slave thread in interrupt driven environment in C
Instead of having your monitoring thread spin on a flag, it could wait until the interrupt handler provides notification that a thread should be spawned. One way to do this is with a semaphore:
sem_t interrupt_sem;
void interrupt_handler(void)
{
sem_post(&interrupt_sem);
}
void monitoring_thread(void)
{
while(1)
{
sem_wait(&interrupt_sem);
//start the thread here
}
}
Previously, I had a solution based on a condition variable, but it is unlikely your system would operate correctly if the interrupt handler makes blocking calls. It could cause a deadlock or other undefined behaviors, as the variables in the system may not have consistent values at the time the interrupt takes place.
As pointed out in comments by myself and others, your operating system should provide some kind of interface to explicitly wake up a waiting task. In the code above, we are assuming the monitoring thread is always active in the background.
you can use POSIX semaphore too
you can wait a semaphore that initial value is 0 by a thread that will be blocked by wait
and post this semaphore in your signal handle function
then , thread above will be waked up and do things you want(create thread)
I am implementing a condition variable's wait operation. I have a struct for my condition variable. So far, my struct has a monitor, a queue, and a spinlock. But I am not sure if a condition variable should have a queue by itself. My notify looks like this:
void uthread_cv_notify (uthread_cv_t* cv) {
uthread_t* waiter_thread;
spinlock_lock(&cv->spinlock);
waiter_thread = dequeue (&cv->waiter_queue);
if(waiter_thread)
{
uthread_monitor_exit(cv->mon);
uthread_stop(TS_BLOCKED);
uthread_monitor_enter(cv->mon);
spinlock_unlock(&cv->spinlock);
}
}
But I wonder if in a notify function or a wait function I should just enqueue and dequeue in the monitor's waiting queue?
Thanks
The signal operation (that you're calling notify) should not require that the monitor be entered. This is inefficient.
It seems like you're trying to implement some clumsy old fashioned condition/monitor system in which the caller of "notify" must be inside the monitor, and it is guaranteed that if a thread is waiting, that thread gets the monitor before the "notify" caller returns to the monitor. (And that waiting thread does not have to have a loop re-testing the condition, either.)
That may be how C. A. R. Hoare initially described monitors and conditions, but the formalism is impractical/inefficient on modern multiprocessor systems, and also on threading implementations which do not have the luxury of being extremely tightly integrated with the low level scheduler (to be able to precisely control which thread gets to run when, so there are no races about who acquires a mutex first: for instance, to be able to transfer a thread from one wait queue to another, etc.)
Note how you're extending the critical section of the monitor over the spinlock_lock operation and over the dequeue operation. Neither of these belong under the monitor. The spinlock is independent, and the queue is guarded by the spinlock, not by the monitor. The monitor should protect the shared variables of the user code only (the special atomic property of of the wait operation).
So why do you need an extra queue? You are already storing all the threads that need to be notified.
Also, you probably want to do something like this:
void uthread_cv_notify (uthread_cv_t* cv) {
uthread_t* waiter_thread;
spinlock_lock(&cv->spinlock);
waiter_thread = dequeue (&cv->waiter_queue);
if(waiter_thread)
{
uthread_monitor_exit(cv->mon);
uthread_stop(TS_BLOCKED);
uthread_monitor_enter(cv->mon);
}
spinlock_unlock(&cv->spinlock);
}
This will ensure that the spin lock is always released.
I am writing a basic user level thread library. The function prototype for thread creation is
thr_create (start_func_pointer,arg)
{
make_context(context_1,start_func)
}
start_func will be user defined and can change depending on user/program
once after creation of thread, if I start executing it using
swapcontext(context_1,context_2)
the function start_func would start running. Now , if a signal comes in , I need to handle it. Unfortunately, I just have the handle to start_func so I cant really define signal action inside the start_func
is there a way I can add a signal handling structure inside the start_function and point it to my code. something like this
thr_create (start_func_pointer,arg)
{
start_func.add_signal_hanlding_Structure = my_signal_handler();
make_context(context_1,start_func)
}
Does anybody know how posix does it ?
If you are talking about catching real signals from the actual operating system you are running on I believe that you are going to have to do this application wide and then pass the signals on down into each thread (more on this later). The problem with this is that it gets complicated if two (or more) of your threads are trying to use alarm which uses SIGALRM -- when the real signal happens you can catch it, but then who do you deliver it to (one or all of the threads?).
If you are talking about sending and catching signals just among the threads within a program using your library then sending a signal to a thread would cause it to be marked ready to run, even if it were waiting on something else previously, and then any signal handling functionality would be called from your thread resume code. If I remember from your previous questions you had a function called thread_yield which was called to allow the next thread to run. If this is the case then thread_yield needs to check a list of pending signals and preform their actions before returning to where ever thread_yield was called (unless one of the signal handlers involved killing the current thread, in which case you have to do something different).
As far as how to implement registering of signal handlers, in POSIX that is done by system calls made by the main function (either directly or indirectly). So you could have:
static int foo_flag = 0;
static void foo_handle(int sig) {
foo_flag = 1;
}
int start_func(void * arg) {
thread_sig_register(SIGFOO, foo_handle);
thread_pause();
// this is a function that you could write that would cause the current thread
// to mark itself as not ready to run and then call thread_yield, so that
// thread_pause() will return only after something else (a signal) causes the
// thread to become ready to run again.
if (foo_flag) {
printf("I got SIGFOO\n");
} else {
printf("I don't know what woke me up\n");
}
return 0;
}
Now, from another thread you can send this thread a SIGFOO (which is just a signal I made up for demonstration purposes).
Each of your thread control blocks (or whatever you are calling them) will have to have a signal handler table (or list, or something) and a pending signal list or a way to mark the signals as pending. The pending signals will be examined (possibly in some priority based order) and the handler action is done for each pending signal before returning to that threads normal code.