pthread_cancel not cancelling all the threads - pthreads

I have 4 threads which all execute the same while loop . After a certain amount of time one of the threads reaches the threshold point and stops execution.
The 3 remaining threads are not getting canceled. I believe the Threshold global variable is visible to all 4 threads. How can I make sure that all the threads suspend execution at the Threshold point?
I have set the following attributes for the threads:
Same lock and unlock MUTEX for all 4 threads
Set pthreads cancel type to ENABLED

Related

Synchronous Counter Overflow ""CANopen""

I faced a new parameter for synchronization in CANopen: Synchronous Counter Overflow.
Synchronous Counter Overflow
The synchronous counter overflow object is an object dictionary entry that defines the maximum value of the SYNC counter.
The SYNC counter is an optional part of an SYNC message.
You can enable the SYNC counter by specifying a non-zero value to the synchronous counter overflow object.
The SYNC counter value starts from 1 and increases by 1 with each SYNC message.
An SYNC cycle is the time period between the time when the SYNC counter value is 1 and the time when the SYNC counter value reaches the synchronous counter overflow value.
At the end of an SYNC cycle, the device sends out the SYNC message with a counter value that equals the synchronous counter overflow value.
The device then resets the SYNC counter value to 1 for the next SYNC message.
The next SYNC message starts another SYNC cycle.
Use the synchronous counter overflow object to ensure periodic SYNC events occur in SYNC cycles with the same SYNC counter value.
You can use specific SYNC counter values to trigger multiple periodic SYNC events.
For example, you can set the periods of event A and event B to 3 and the period of event C to 4. You then set the synchronous counter overflow to 12.
When you execute the application, event A and event B occur when the SYNC counter is 3, 6, 9, and 12. Event C occurs when the SYNC counter is 4, 8, and 12.
https://www.ni.com/docs/en-US/bundle/ni-industrial-communications-canopen/page/canopenhelp/canopen_sync_object.html
I know that we can set this object in command 0x1019 to count SYNC messages, and of course, a maximum is set for it, but I don't understand why this is used.
It's just a counter with configurable overflow. Devices can use it for whatever, so check the docu of your devices (or pick your use-case if you are writing your own). For many applications you don't even need sync at all.
According to [1] it is commonly used to distribute bus load. You certainly can do a lot of applications without it, simply doing everything at the same period. It's easy to calculate the bus load in this case to avoid overload. Especially because the COB-IDs also imply strict priorities, so you can have "background traffic" that doesn't invalidate your calculations for the high-priority messages.
[1] https://www.can-cia.org/can-knowledge/canopen-fd/sync-protocol/

What's the case for semaphore passing a value greater than zero

Most of the articles I've found are using semaphore for usage of waiting a task finished, then do the rest of tasks. In this case, semaphore is always start with a value 0, and then increase the value in the completeHandler.
However, according to documentation:
Passing a value greater than zero is useful for managing a finite pool of resources, where the pool size is equal to the value
I've tried to find an example for this case, but which turn out all I've found are talking about using dispatch_group_wait for waiting for multiple tasks finished. Would someone please give me an example and scenario for the case using a semaphore with a init value greater than 0?

iOS GCD custom concurrent queue execution sequence

I have question regarding this issue ,
According to Apple's documents
Concurrent
Concurrent queues (also known as a type of global dispatch queue) execute one or more tasks concurrently, but tasks are still started in the order in which they were added to the queue. The currently executing tasks run on distinct threads that are managed by the dispatch queue. The exact number of tasks executing at any given point is variable and depends on system conditions.
In iOS 5 and later, you can create concurrent dispatch queues yourself by specifying DISPATCH_QUEUE_CONCURRENT as the queue type. In addition, there are four predefined global concurrent queues for your application to use. For more information on how to get the global concurrent queues, see Getting the Global Concurrent Dispatch Queues.
And i do a test, using the sample code ,
dispatch_queue_t concurrentQueue;
concurrentQueue = dispatch_queue_create("com.gcd.concurrentQueue",
DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^{
NSLog(#"First job ");
});
dispatch_async(concurrentQueue, ^{
NSLog(#"Second job");
});
dispatch_async(concurrentQueue, ^{
NSLog(#"Third job ");
});
But the results seems not as the order in which they are added, here is the results,
2015-06-03 18:36:38.114 GooglyPuff[58461:1110680] First job
2015-06-03 18:36:38.114 GooglyPuff[58461:1110682] Third job
2015-06-03 18:36:38.114 GooglyPuff[58461:1110679] Second job
So my question is , shouldn't it be
First, Second , Third ?
Any advice is welcome , and thanks for your help.
"Concurrent" means they run at the same time and no assumptions should be made about where in their progress any of them will be at any given moment and which will finish first. That is the whole meaning and implication of concurrency: between one line of code and the next in one concurrent operation - even during one line of code - anything else from any other concurrent operation might be happening.
So, in answer to your particular question, these tasks may have started in a known order, but that happened very quickly, and after that point their progress is interleaved unpredictably. And your NSLog calls are part of that progress; they do not, and cannot, tell you when the tasks started!
The documentation is correct - they will indeed start in the order you added them to the queue. Once in the queue, they will be started one after the other, but on concurrent threads. The order they will finish is dependent on how long the task will take to execute. Here's a thought experiment, imagine your code was like this instead:
dispatch_async(concurrentQueue, ^{
JobThatTakes_3_SecToExecute(); // Job 1 (3 seconds to execute)
});
dispatch_async(concurrentQueue, ^{
JobThatTakes_2_SecToExecute(); // Job 2 (2 seconds to execute)
});
dispatch_async(concurrentQueue, ^{
JobThatTakes_1_SecToExecute(); // Job 3 (1 second to execute)
});
The overhead in and out of the queue should be very small compared to these job lengths, so you would expect them to finish up in about the time that their task takes to execute. In this case they'd finish roughly 1 second apart starting with Job 3, then 2, then 1. The total time the queue would take to complete will be about the length of Job 1, since it takes the longest to execute. This is lovely, since the total time is set primarily by the longest job, not the sum of the jobs. However, you don't have any say in what order they finish, since that's dictated by the task duration.
Change dispatch_async to dispatch_sync in this example and the queue will take about 6 seconds to complete. They'll come out in this order: Job 1, 2, then 3. This will guarantee that your results come out in the order you wanted, but it will take much longer.
So back to the significance of what the docs mean by "tasks are still started in the order in which they were added to the queue" for concurrent queues. This will be noticeable if your job is resource constrained. Say you're putting a big pile of long duration tasks in a concurrent queue on a 2 CPU machine. It is unlikely you'll be able to run a dozen CPU-pegging tasks concurrently here; some will have to wait while others run. The order that you put them into the queue will decide who gets to run next as resources free up. In your example, the tasks are of super short duration and involve console locking (as Rob mentioned), so queue / locking overhead can mess with your expectations.
Another (probably more important) reason the order of execution in concurrent queues matter is when barriers are used. You may need to run some sort of a task every N other tasks, which is where a barrier would come in handy. The fixed order of execution will assure that the barrier executes after N tasks have completed concurrently, provided you put the barrier in the queue in the right spot.

NSCondition, what if no lock when call signal?

From this Apple's document about NSCondition, the usage of NSCondition should be:
Thead 1:
[cocoaCondition lock];
while (timeToDoWork <= 0)
[cocoaCondition wait];
timeToDoWork--;
// Do real work here.
[cocoaCondition unlock];
Thread 2:
[cocoaCondition lock];
timeToDoWork++;
[cocoaCondition signal];
[cocoaCondition unlock];
And in the document of method signal in NSConditon:
You use this method to wake up one thread that is waiting on the condition. You may call this method multiple times to wake up multiple threads. If no threads are waiting on the condition, this method does nothing. To avoid race conditions, you should invoke this method only while the receiver is locked.
My question is:
I don't want the Thread 2 been blocked in any situation, so I removed the lock and unlock call in Thread 2. That is, Thread 2 can put as many work as it wish, Thread 1 will do the work one by one, if no more work, it wait (blocked). This is also a producer-consumer pattern, but the producer never been blocked.
But the way is not correct according to Apple's document So what things could possibly go wrong in this pattern? Thanks.
Failing to lock is a serious problem when multiple threads are accessing shared data. In the example from Apple's code, if Thread 2 doesn't lock the condition object then it can be incrementing timeToDoWork at the same time that Thread 1 is decrementing it. That can result in the results from one of those operations being lost. For example:
Thread 1 reads the current value of timeToDoWork, gets 1
Thread 2 reads the current value of timeToDoWork, gets 1
Thread 2 computes the incremented value (timeToDoWork + 1), gets 2
Thread 1 computes the decremented value (timeToDoWork - 1), gets 0
Thread 2 writes the new value of timeToDoWork, stores 2
Thread 1 writes the new value of timeToDoWork, stores 0
timeToDoWork started at 1, was incremented and decremented, so it should end at 1, but it actually ends at 0. By rearranging the steps, it could end up at 2, instead. Presumably, the value of timeToDoWork represents something real and important. Getting it wrong would probably screw up the program.
If your two threads are doing something as simple as incrementing and decrementing a number, they can do it without locks by using the atomic operation functions, such as OSAtomicIncrement32Barrier() and OSAtomicDecrement32Barrier(). However, if the shared data is any more complicated than that (and it probably is in any non-trivial case), then they really need to use synchronization mechanisms such as condition locks.

Mutex are needed to protect the Condition Variables

As it is said that Mutex are needed to protect the Condition Variables.
Is the reference here to the actual condition variable declared as pthread_cond_t
OR
A normal shared variable count whose values decide the signaling and wait.
?
is the reference here to the actual condition variable declared as pthread_cond_t or a normal shared variable count whose values decide the signaling and wait?
The reference is to both.
The mutex makes it so, that the shared variable (count in your question) can be checked, and if the value of that variable doesn't meet the desired condition, the wait that is performed inside pthread_cond_wait() will occur atomically with respect to that check.
The problem being solved with the mutex is that you have two separate operations that need to be atomic:
check the condition of count
wait inside of pthread_cond_wait() if the condition isn't met yet.
A pthread_cond_signal() doesn't 'persist' - if there are no threads waiting on the pthread_cond_t object, a signal does nothing. So if there wasn't a mutex making the two operations listed above atomic with respect to one another, you could find yourself in the following situation:
Thread A wants to do something once count is non-zero
Thread B will signal when it increments count (which will set count to something other than zero)
thread "A" checks count and finds that it's zero
before "A" gets to call pthread_cond_wait(), thread "B" comes along and increments count to 1 and calls pthread_cond_signal(). That call actually does nothing of consequence since "A" isn't waiting on the pthread_cond_t object yet.
"A" calls pthread_cond_wait(), but since condition variable signals aren't remembered, it will block at this point and wait for the signal that has already come and gone.
The mutex (as long as all threads are following the rules) makes it so that item #2 cannot occur between items 1 and 3. The only way that thread "B" will get a chance to increment count is either before A looks at count or after "A" is already waiting for the signal.
A condition variable must always be associated with a mutex, to avoid the race condition where a thread prepares to wait on a condition variable and another thread signals the condition just before the first thread actually waits on it.
More info here
Some Sample:
Thread 1 (Waits for the condition)
pthread_mutex_lock(cond_mutex);
while(i<5)
{
pthread_cond_wait(cond, cond_mutex);
}
pthread_mutex_unlock(cond_mutex);
Thread 2 (Signals the condition)
pthread_mutex_lock(cond_mutex);
i++;
if(i>=5)
{
pthread_cond_signal(cond);
}
pthread_mutex_unlock(cond_mutex);
As you can see in the same above, the mutex protects the variable 'i' which is the cause of the condition. When we see that the condition is not met, we go into a condition wait, which implicitly releases the mutex and thereby allowing the thread doing the signalling to acquire the mutex and work on 'i' and avoid race condition.
Now, as per your question, if the signalling thread signals first, it should have acquired the mutex before doing so, else the first thread might simply check the condition and see that it is not being met and might go for condition wait and since the second thread has already signalled it, no one will signal it there after and the first thread will keep waiting forever.So, in this sense, the mutex is for both the condition & the conditional variable.
Per the pthreads docs the reason that the mutex was not separated is that there is a significant performance improvement by combining them and they expect that because of common race conditions if you don't use a mutex, it's almost always going to be done anyway.
https://linux.die.net/man/3/pthread_cond_wait​
Features of Mutexes and Condition Variables
It had been suggested that the mutex acquisition and release be
decoupled from condition wait. This was rejected because it is the
combined nature of the operation that, in fact, facilitates realtime
implementations. Those implementations can atomically move a
high-priority thread between the condition variable and the mutex in a
manner that is transparent to the caller. This can prevent extra
context switches and provide more deterministic acquisition of a mutex
when the waiting thread is signaled. Thus, fairness and priority
issues can be dealt with directly by the scheduling discipline.
Furthermore, the current condition wait operation matches existing
practice.
I thought that a better use-case might help better explain conditional variables and their associated mutex.
I use posix conditional variables to implement what is called a Barrier Sync. Basically, I use it in an app where I have 15 (data plane) threads that all do the same thing, and I want them all to wait until all data planes have completed their initialization. Once they have all finished their (internal) data plane initialization, then they can start processing data.
Here is the code. Notice I copied the algorithm from Boost since I couldnt use templates in this particular application:
void LinuxPlatformManager::barrierSync()
{
// Algorithm taken from boost::barrier
// In the class constructor, the variables are initialized as follows:
// barrierGeneration_ = 0;
// barrierCounter_ = numCores_; // numCores_ is 15
// barrierThreshold_ = numCores_;
// Locking the mutex here synchronizes all condVar logic manipulation
// from this point until the point where either pthread_cond_wait() or
// pthread_cond_broadcast() is called below
pthread_mutex_lock(&barrierMutex_);
int gen = barrierGeneration_;
if(--barrierCounter_ == 0)
{
// The last thread to call barrierSync() enters here,
// meaning they have all called barrierSync()
barrierGeneration_++;
barrierCounter_ = barrierThreshold_;
// broadcast is the same as signal, but it signals ALL waiting threads
pthread_cond_broadcast(&barrierCond_);
}
while(gen == barrierGeneration_)
{
// All but the last thread to call this method enter here
// This call is blocking, not on the mutex, but on the condVar
// this call actually releases the mutex
pthread_cond_wait(&barrierCond_, &barrierMutex_);
}
pthread_mutex_unlock(&barrierMutex_);
}
Notice that every thread that enters the barrierSync() method locks the mutex, which makes everything between the mutex lock and the call to either pthread_cond_wait() or pthread_mutex_unlock() atomic. Also notice that the mutex is released/unlocked in pthread_cond_wait() as mentioned here. In this link it also mentions that the behavior is undefined if you call pthread_cond_wait() without having first locked the mutex.
If pthread_cond_wait() did not release the mutex lock, then all threads would block on the call to pthread_mutex_lock() at the beginning of the barrierSync() method, and it wouldnt be possible to decrease the barrierCounter_ variables (nor manipulate related vars) atomically (nor in a thread safe manner) to know how many threads have called barrierSync()
So to summarize all of this, the mutex associated with the Conditional Variable is not used to protect the Conditional Variable itself, but rather it is used to make the logic associated with the condition (barrierCounter_, etc) atomic and thread-safe. When the threads block waiting for the condition to become true, they are actually blocking on the Conditional Variable, not on the associated mutex. And a call to pthread_cond_broadcast/signal() will unblock them.
Here is another resource related to pthread_cond_broadcast() and pthread_cond_signal() for an additional reference.

Resources