With regards to atomic property, Apple's documentation has this below:
This means that the synthesized accessors ensure that a value is
always fully retrieved by the getter method or fully set via the
setter method, even if the accessors are called simultaneously from
different threads.
What does "fully retrieved" or "fully set" mean?
Why is "fully retrieved" or "fully set" not enough to guarantee thread safety?
Note: I am aware there are many posts regarding atomicity on SO, please don't tag this as duplicate unless the ticket specifically address the question above. After reading the posts, I still do not fully understand atomic property.
Atomic means that calls to the getter/setter are synchronized. That way if one thread is setting the property at the same time as another thread is getting it, the one getting the property is guaranteed to get a valid return value. Without it being atomic, it would be possible that the getter retrieves a garbage value, or a pointer to an object that is immediately deallocated. When it's atomic, it will also ensure that if two threads try to set it at the same time, one will wait for the other to finish. If it weren't atomic and two threads tried to set it at the same time, you could end up with a garbage value being written, or possibly objects being over/under retained or over/under released.
So basically, if the property is being set, any other calls to set it or get it will wait for the method to return. Same for if the property is being gotten, any other calls to get it or set it will wait until that get finishes.
This is sometimes sufficient for thread safety depending on what it's being used for. But often you want more than this level of synchronization for thread safety. For example if one block of code on a thread gets the value, makes some change to it, and wants to set it again without some other thread changing it in the meantime. You would have to do additional synchronization to make sure that you have a lock on it from before you get it until after you subsequently set it. You would want to do the same if you wanted to get an object and make some changes to that object without another thread trying to make changes at the same time on it.
"Fully set" and "fully retrieved" means the code below will always print "0x11111111" or "0x22222222". It will never print things like "0x11112222" or "0x11221122". Without atomic or some other appropriate thread synchronization, those sorts of partial reads or partial updates are allowed for some data types on some CPU architectures.
// Thread 1
while (true) x = 0x11111111;
// Thread 2
while (true) x = 0x22222222;
// Thread 3
while (true) printf("0x%x\n", x);
It means the value will never be accessed when it's halfway through being written. It will always be one intended value or another, never an incompletely altered bit pattern.
It isn't enough to guarantee thread-safety because ensuring that the value of a variable is either fully written or nor written at all is not enough to make all the code that uses that variable thread-safe. For example, there might be two variables that need to be updated together (the classical example is transferring credits from one account to another), but code in another thread could see one variable with the new value and one with the old.
Very often, you'll need to implement synchronization for whole systems, so the guarantees offered by atomic variables end up almost not mattering a lot of the time.
Related
I have a block of code like this in kotlin.
synchronized(this) {
// do some work and produces a String
}.also { /*it: String*/
logger.log(it)
}
can some thread come and with unlucky timing the it variable gets changed before logging happens? (There are a lot of threads executing this piece of code concurrently)
To expand on comments:
The synchronized block returns a reference that's passed into the also block as it; that reference is local to the thread, and so there's no possibility of it being affected by other threads.
In general, there's no guarantee about the object that that reference points to: if other threads have a reference to it, they could potentially change its state (or that of other objects it refers to).But in this case, it's a String; and in Kotlin, Strings are completely immutable. So there's no risk of that here.
Taking those together: the logging in OP's code is indeed thread-safe!
However:
We can't tell whether there could be race conditions or other concurrency issues within the synchronized block, before the String gets created and returned. It synchronizes on this, which prevents two threads simultaneously executing it on the same object; but if there are two instances of the class, each one could have a single thread running it.So for example there could be an issue if the block uses some common object that's not completely thread-safe, or some instance property that's set to the same reference in both instances, or if there's sharing in a more roundabout way. Obviously, this will depend upon the nature of the work done in that block, what objects it accesses, and what it does with them. So that's worth bearing in mind too.
I am creating a local event monitor in Objective-C using the Cocoa framework and wondered if this would introduce a race condition or not:
id monitor = [NSEvent addLocalMonitorForEventsMatchingMask:
(NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown | NSEventMaskOtherMouseDown)
handler:^(NSEvent* event)
{
[NSEvent removeMonitor:monitor];
}];
Your code does not compile as the block does not return a value, so maybe you've simplified this too much for posting.
Next the value of monitor within the block will always be nil as its value is copied as part of block construction before addLocalMonitorForEventsMatchingMask returns and a value is assigned to monitor.
You could address this last issue by declaring monitor to be __block, thus capturing the variable rather than its value, however that gets you to:
You've got a reference cycle. The opaque monitor object returned by addLocalMonitorForEventsMatchingMask contains within it a reference to your block, and your block contains a reference to the monitor object. This won't effect the operation of the monitoring or its removal, it will just mean the monitor object & block objects will never get collected. You could address this by niling monitor in the block when you do removeMonitor.
Which gets us to your final question, is there a race condition? Presumably you mean between the event system calling your monitor for one event and trying to call it on a following event. I don't know if we can say for sure, however the documentation for removeMonitor does not mention any precautions to take, and initial event processing is done through a "queue" suggesting the system will not start processing a following event until it has at least dispatched the current one to your app. This does strongly suggest that race conditions are not an issue here.
Note however that the documentation, even the Swift version, uses the term "garbage collection" and though ARC is a type of GC Apple tends to reserve the term for the long deprecated pre-ARC (and pre-Swift) garbage collector - suggesting the documentation has not been revised for eons (in computer terms). Maybe someone else will offer a definitive answer on this.
HTH
I have BBController instances (my custom objects), where some may need to wait for a few others to complete first (dependencies). I have decided to have each controller lock some synchronisation object at initialisation, lets call it a Padlock, and then unlock it when its done processing. When its unlocked, any controllers that depend (or were waiting for) on the aforementioned controller can then continue. So this is not about protecting a section of code by allowing one thread, but instead telling anything that that depends on an output to wait until that output is available.
I have experience with Semaphores in objective c, so I thought I could use those here by having each controller initialise its semaphore with a value of 0, and then when finished signal it with a value of infinite or max. While that would work, I'm sure there is a better locking object to make use of, since the value property of Semaphore is of no use here since as many BBControllers can continue when the semaphore is signalled. I am new to VB.Net
I have read some stuff on ios sdk about multithreading, but I still didn't find the answer to the problem:
In the main thread I have a property, the program does some stuff in a thread, where the value of the property is changed, the other thread needs that changed value.
So how can I change the value of a property or a field in one thread, so that it would change for all threads?
Changing a property on a single object changes the value "for all threads" basically. There's no thread-specific copies of objects unless you make them yourself.
For multithreaded programs, the major challenge is making sure two threads aren't trying to access/write the same memory (a property, in your case) at the same time. Easiest way (but not necessarily most efficient, or fool-proof way) to do this for your property in question is to exclude the "nonatomic" attribute from your property declaration.
(EDIT: this assumes you're using #synthesize to implement your properties, and not #dynamic nor have custom overriding getters or setters.)
Multi-threading is a bit of a large topic to cover here, but Apple's documentation is a good place to start for more info: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html
May be my question is stupid. But i would like to get it cleared. We know that functions are loaded in memory only once and when you create new objects, only instance variables gets created, functions are never created. My question is, say suppose there is server and all clients access a method named createCustomer(). Say suppose all clients do something which fired createCustomer on server. So, if the method is in middle of execution and new client fires it. Will the new request be put on wait? or new request also will start executing the method? How does it all get managed when there is only one copy of function in memory? No book mentions answers to this type of questions. So i am posting here where i am bound to get answers :).
Functions are code which is then executed in a memory context. The code can be run many times in parallel (literally in parallel on a multi-processor machine), but each of those calls will execute in a different memory context (from the point of view of local variables and such). At a low level this works because the functions will reference local variables as offsets into memory on something called a "stack" which is pointed to by a processor register called the "stack pointer" (or in some interpreted languages, an analog of that register at a higher level), and the value of this register will be different for different calls to the function. So the x local variable in one call to function foo is in a different location in memory than the x local variable in another call to foo, regardless of whether those calls happen simultaneously.
Instance variables are different, they're referenced via a reference (pointer) to the memory allocated to the instance of an object. Two running copies of the same function might access the same instance variable at exactly the same time; similarly, two different functions might do so. This is why we get into "threading" or concurrency issues, synchronization, locks, race conditions, etc. But it's also one reason things can be highly efficient.
It's called "multi-threading". If each request has its own thread, and the object contains mutable data, each client will have the opportunity to modify the state of the object as they see fit. If the person who wrote the object isn't mindful of thread safety you could end up with an object that's in an inconsistent state between requests.
This is a basic threading issue, you can look it up at http://en.wikipedia.org/wiki/Thread_(computer_science).
Instead of thinking in terms of code that is executed, try to think of memory context of a thread that is changed. It does not matter where and what the actual code happens to be, and if it is the same code or a duplicate or something else.
Basically, it can happen that the function is called while it was already called earlier. The two calls are independent and may even happen to run in parallel (on a multicore machine). The way to achieve this independence is by using different stacks and virtual address spaces for each thread.
There are ways to synchronize calls, so additional callers have to wait until the first call finishes. This is also explained in the above link.