Is it possible to build a sort of combined semaphore/spin lock in C?
That is, I want a thread control structure which supports:
Periodically waking up the thread to check the state of some variable. (like a spin lock)
Automatically waking the thread early if the state of the structure is altered by another thread (like sem_wait/sem_post).
For example in a program like this:
Parent:
while(something){
//do some stuff here.
sem_post(child_sem);
sem_wait(parent_sem);
}
Child:
while(something_else){
sem_wait(child_sem);
//do some other stuff here.
sem_post(parent_sem);
}
I would like the parent to unblock if the child fails to set parent_sem within 5 seconds, but also to unblock before 5 seconds have passed if the child has set parent_sem early, while minimizing the number of CPU cycles expended checking and re-checking the state of parent_sem over those 5 seconds. I know I can do this with a spin lock, but setting the waiting period to be high (i.e. 1 second) means wasting almost 1 second most of the time. Setting it to be low (e.g. 100ms) means doing 50 checks in the event the child times out. Neither of these is a nice solution.
This is exactly what timed locks are for. Depending on your library, they may or may not be available.
Your example:
Parent:
while(something){
//do some stuff here.
sem_post(child_sem);
while (sem_timed_wait(parent_sem, MAX_WAIT_TIME) == TIMEOUT)
// check whether you should still continue waiting
}
Child:
while(something_else){
while (sem_timed_wait(child_sem, MAX_WAIT_TIME) == TIMEOUT)
// check whether you should still continue waiting
//do some other stuff here.
sem_post(parent_sem);
}
I have used this method to increase robustness of my threads. That is, you don't want your threads to be blocked indefinitely, because there may be an error and you want to terminate them, or you may simply want to ask them to exit. On the other hand you would want to wake up as soon as possible.
This solution satisfies both conditions.
Related
There are linux kernel threads that do some work every now and then, then either go to sleep or block on a semaphore. They can be in this state for several seconds - quite a long time for a thread.
If threads need to be stopped for some reason, at least if unloading the driver they belong to, I am looking for a way to get them out of sleep or out of the semaphore without waiting the whole sleep time or triggering the semaphore as often as required.
I found and read a lot about this but there are multiple advises and I am still not sure how things work. So if you could shed some light on that.
msleep_interruptible
What is able to interrupt that?
down_interruptible
This semaphore function implies interrupt-ability. Same here, what can interrupt this semaphore?
kthread_stop
It's described as sets kthread_should_stop to true and wakes it... but this function blocks until the sleep time is over (even if using msleep_interruptible) or the semaphore is triggered.
What am I understanding wrong?
Use a signal to unblock - really?
My search found a signal can interrupt the thread. Other hits say a signal is not the best way to operate on threads.
If a signal is the best choice - which signal do I use to unblock the thread but not mess it up too much?
SIGINT is a termination signal - I don't intend to terminate something, just make it go on.
More information
The threads run a loop that checks a termination flag, does some work and then block in a sleep or a semaphore. They are used for
Situation 1.
A producer-consumer scenario that uses semaphores to synchronize producer and consumer. They work perfectly to make threads wait for work and start running on setting the semaphore.
Currently I'm setting a termination flag, then setting the semaphore up. This unblocks the thread which then checks the flag and terminates. This isn't my major problem. Hovever of course I'd like to know about a better way.
Code sample
while (keep_running) {
do_your_work();
down_interruptible(&mysemaphore); // Intention: break out of this
}
Situation 2.
A thread that periodically logs things. This thread sleeps some seconds between doing it's work. After setting the flag this thread terminates at it's next run but this can take several seconds. I want to break the sleep if necessary.
Code sample
while (keep_running) {
do_your_work();
msleep(15000); // Intention: break out of this - msleep_interruptible?
}
For a simple sampling profiler I'm suspending a target thread, get its current stacktrace, then continue it.
Now I would like to highlight a sample differently if the thread was in a waiting state.
So I want to know if the thread was blocking (waiting via WaitForSingleObject, pausing via Sleep, ...) at the time it was suspended.
I can get this information via NtQuerySystemInformation(SystemProcessInformation), but that gets much more than needed, the information of each thread of each process.
Also I saw Performance Counters, but I'm not sure if it's possible with this API, if I only have the thread ID/handle.
UPDATE:
IInspectable gave me a hint with Wait Chain Traversal, while it seemed a good fit, it gives back the status ObjectStatus==WctStatusBlocked for all suspended threads, which isn't unreasonable, but doesn't work for my problem. It is also very slow, I assume because it collects the data for the whole chain, while I only care for the first element.
While not exactly what I wanted, QueryThreadCycleTime is close enough.
So each time the thread is suspended, QueryThreadCycleTime is called, which returns the number of CPU clock cycles used by this thread up to this point.
If the difference to the previous call is below a certain limit, the current sample is then considered as waiting.
It's not perfect, the first sample taken while the thread entered a waiting state is not detected as waiting, and the limit might not work for all CPUs the same.
I have something like a list of things to calculate, and they are somewhat dependent on eachother (some of those calculations, may show that other calculations on the list are not needed).
Also I want to calculate always two of them at a time (two child threads and one main thread (which is a child thread of another one, but that's another story)).
So I want the main thread to wait for ANY of the two treads -the one that finishes first makes the main thread continue-. After it continues, it will run some code to see if the other running thread can be killed (if the one that finished shows that the other is not needed), or not, and also to run a new thread.
The idea is to do something like this:
while (/*list not empty*/) {
/*detect which two entries need to be calculated*/
/*detect if running thread can be killed*/
if (/*running thread can be killed*/) {
pthread_join(/*threadnum*/, NULL)
}
switch (/*how many threads already running?*/) {
case 0:
pthread_create(/*&threadnum*/, NULL, /*calculate*/, /*foo*/);
case 1:
pthread_create(/*&threadnum*/, NULL, /*calculate*/, /*foo*/);
break;
}
/* !!!!!!!!! Question code is next line: !!!!!!!!!*/
pthread_join(/*What goes here?*/, NULL);
// If it is impossible to do with pthread_join, what else can be used?
}
My first approach (if this was impossible) would be to store in an array the status of both threads, and check every second (with a while and sleep(1)) if any of them finished, but that would make me lose time (between 0 and 1 seconds) every time a thread finishes. So I want to avoid that if possible.
EDIT: pthread_cond_wait(/* something */) seems the way to go. However I want it to be easy: the main thread and both child threads share a global variable (parent) that is set to 0 if child threads are running, and is set to 1 when one of them stops. Ideally I want to control from the main thread everything in this way:
while (/*list not empty*/) {
/*detect which two entries need to be calculated*/
/*detect if running thread can be killed*/
if (/*running thread can be killed*/) {
pthread_join(/*threadnum*/, NULL)
}
switch (/*how many threads already running?*/) {
case 0:
pthread_create(/*&threadnum*/, NULL, /*calculate*/, /*foo*/);
case 1:
pthread_create(/*&threadnum*/, NULL, /*calculate*/, /*foo*/);
break;
}
/* !!!!!!!!! Question code is next line: !!!!!!!!!*/
pthread_cond_wait(parent, /*wtf?*/)
}
Now I have an idea to stop the parent until that condition is met, which I can set to 1 inside the child threads.
Instead of making the main thread monitor and try to kill other threads, make the other threads communicate directly amongst themselves.
For example, if thread A finishes and it becomes clear that the computation in thread B is no longer needed, simply set a boolean flag. Make thread B check that flag between steps of its computation, and give up if the flag is set.
Trying to interrupt threads is bad practice--you're better off just setting a flag that the threads will check.
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."
I am confused about the process switching between two processes. When a new process is created using fork, what are the general rules applicable for switching between processes. Is it only when one processes goes to idle state? I have few doubts
What will happen when parent and child in both infinite loop and having only print instruction (no sleep method)
What is the general rule?
Most preemptive schedulers will, highly simplified, allocate a certain maximum time to each process.
When that time expires (for instance 10 ms), it will re-schedule so that other processes get some CPU.
If the timer doesn't expire before the process hits some other wait condition (such as doing I/O), it will re-schedule then, instead.
When the quantum expires context switch occurs
When theresource.
When there is a system call triggered ==> not sure.
re is an interrupt switching occurs
when another process/thread with higher priority comes in ready state, context switch triggered.
When your thread goes to blocked state by virtue of i/o or awaiting any other thread whcih share's the locked