How global variables to be accessed in multi-thread env? - objective-c

How global variables to be accessed in multi-thread env? Eg: the following messageServerUrl variable how to keep it thread safe? Is it atomic enough to keep safe? If not, any other solution available? Any idea please share, thanks in advance.
#property(atomic, copy) NSString * messageServerUrl;

atomic doesn't magically keep something thread-safe. It just makes a thread-safe accessor method.
Being very very very careful is what makes a shared value safe (and sometimes not even that!). You could still mess up your life seriously if you accessed the same value from two different threads in a way that puts your logic at risk.
If you know, for example, that this value is set before the secondary thread kicks off, and all you ever do after that is use the getter, then yes, that's probably safe.
But the safest way to share data between multiple threads is: don't. If the data doesn't need to be changed, then pass it to the secondary thread at the outset. This is why GCD is so wonderful: it's serial queues by default, plus you keep passing the data down into the block executed on the next thread, so you get effective locking without locks (which are easy to mismanage).

Related

What's the proper way to have a Thread-Unsafe object in a singleton?

Let's say we have a NSMutableArray for example on a singleton object. The singleton object can obviously be called from multiple different threads.
Let's say we need users of the singleton to be able to addObjects or removeObjects. Or perhaps we have a custom object that we need to both set and read.
What's the proper way to handle these cases? Should every thread-unsafe property on a singleton have it's own serial/concurrent queue, and then overwrite addObject and removeObject functions for the NSMutableArray, wrapping reads in dispatch_sync, and writes in either dispatch_async(to a serial queue) or dispatch_barrier_async(to a concurrent queue)?
1) Does every thread-unsafe property need its own queue? Or should it at least have one in terms of performance. If multiple properties shared the same queue, it would be slower than necessary.
2) In what cases is this thread protection unnecessary. Ever? Or should thread-unsafe properties always have their setters and getter overwritten.
1) Does every thread-unsafe property need its own queue? Or should it
at least have one in terms of performance. If multiple properties
shared the same queue, it would be slower than necessary.
Depends entirely on how frequently you are pounding on the serialized APIs. Start with a simple model and then move to more complex if needed.
And keep in mind that the implementation isn't necessarily limited to just adding queues at whim.
You could also use a multiple-reader, one writer model. That would involve keeping an NSArray* copy of the mutable array's contents that the readers can simultaneously hit. If the mutable array's contents are changed, then you can (thread safety in mind) swap a new immutable copy of the mutable array for the existing NSArray * (could be done with an atomic #property or you could use a concurrent queue for all reads with a barrier for the swap operation).
Something like the above might make sense when either the array is relatively small (cheap copies) or there are many many times more reads than writes.
2) In what cases is this thread protection unnecessary. Ever? Or
should thread-unsafe properties always have their setters and getter
overwritten.
A mutable collection is always thread unsafe, even when operating in a "readonly" mode. Only immutable collections are thread safe.
So, yes, you need to make sure you serialize any operation that would cause a thread unsafe action.

Objective-C: atomic property is fully retrieved

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.

Does atomic actually mean anything for a synthesized primitive?

In Android, I could safely access and modify primitive types from different threads. I used this to share data between my OpenGL draw loop and user settings that were modified in the main thread Android UI. By storing each setting in a primitive type and making each independent of the others' values, it was thread-safe to modify all these variables without using locks or the synchronize keyword.
Is this also true in Objective-C? I read that placing atomic on a variable essentially causes the synthesized getter and setter to use locks, similar to using synchronized methods in Java. And I've read that the reason for this is so an object does not get partially modified while it's being read by another thread.
But are primitive types safe from being partially modified, as they are in Java? If that is the case, it seems like I could use my same old paradigm from Java for sharing data between threads. But then the atomic keyword would be pointless for a primitive, correct?
I also read that a more robust and faster solution than using atomic variables is to copy objects before using them if they are accessed from multiple threads. But I'm not sure how that could be accomplished. Couldn't a nonatomic object get modified while it's in the process of being copied, thereby corrupting the copy?
Primitive types aren't guaranteed to be safe from being partially modified because modifications to primitive types aren't guaranteed to be atomic in C and Objective-C inherits from there. C's only guarantees concern sequence points and there's no requirement that the processing between two sequence points be atomic — a rule of thumb is that each full expression is a sequence point.
In practice, modifying primitives is often a two-step process; the modification is made in a register and then written out to memory. It's very unlikely that the write itself will not be atomic but there's also no guarantee of when it will occur versus the modification. Even with the volatile qualification, the only guarantees provided are in terms of sequence points.
Apple exposes some C functions for atomic actions via OSAtomic.h that map directly to the specialised atomic instructions that CPUs offer for the implementation of concurrency mechanisms. It's possible you could use one of those more directly than via a heavy-handed mutex.
Common patterns in Objective-C are:
immutable objects and functional transformations — there are memory management reasons as well but that's partly why NSString, NSArray, etc, are specifically distinct from NSMutableString, NSMutableArray, etc;
serial dispatch queues, which can be combined with copy-modify-replace by copying on the queue, going off somewhere else to modify, then jumping back onto the queue to replace;
such #synchronizeds, NSConditionLocks or other explicit synchronisation mechanisms as are appropriate.
The main thread itself is a serial dispatch queue, which is why you can ignore the issue of concurrency entirely if you restrict yourself to it.
Atomic synthesized #properties are immune to concurrent partial updates. The accessor methods will use a lock if necessary on that architecture.
In general, primitive types in C are not necessarily safe with respect to concurrent partial updates.
I don't believe you can partially modify a primitive type, that's part of what makes them primitive. You either modify it or you don't. In that sense, I would say that they are thread safe.
You are correct when you say that the atomic keyword would be pointless for a primitive type.
Someone already took a stab at this here:
Objective-c properties for primitive types

Strategy for a self-retaining and self-releasing object

I need to implement a bit of functionality that can be used from a few different places in an application. It's basically sending something over the network, but I don't need it to be attached to any particular view - I can communicate everything to the user by UIAlertViews.
What I would like to do is encapsulating the functionality in an object (?) that can maintain it's own state for a while and then disappear all by itself. I've read in several similar topics that it's generally not advised to have an object that retains and then releases itself, but on the other hand you have singletons which apart from the fact that they never get released, are very similar in nature. You don't need to keep reference to them just to use them properly. In my situation however I feel it woud be somewhat wasteful to create a singleton and then keep it alive for something that takes a few seconds to execute.
What I came up with is a static dictionary local to the class, that keeps unique references to the instances of the class, and then, when an instance is done with its task, it performs selector 'removeObjectForKey' after delay which removes the only existing reference and effectively kills the object. This way I keep only a dictionary in memory which for the most time is empty anyway.
The question is: are there any unexpected side effects of such a solution that I should be aware of and are there any other good patterns for described situation?
So basically instead of a persistent object of your own class, you've got a persistent object of type NSDictionary? How does that help matters? Is your object unusually large? If you are making your codebase more complicated for the sake of a few bytes, that's not a good tradeoff.
Especially now ARC is commonplace, this kind of trickery is usually not a good idea. Have you measured how much memory a singleton approach takes and found it to be a problem? Unless you have done this, use a singleton. It's simpler code, and all other things being equal, simpler code is far better.

nonatomic in multi threaded iOS environment

Most iPhone code examples use the nonatmoc attribute in their properties. Even those that involve [NSThread detachNewThreadSelector:....]. However, is this really an issue if you are not accessing those properties on the separate thread?
If that is the case, how can you be sure nonatomic properties won't be accessed on this different in the future, at which point you may forget those properties are set as nonatomic. This can create difficult bugs.
Besides setting all properties to atomic, which can be impractical in a large app and may introduce new bugs, what is the best approach in this case?
Please note these these questions are specifically for iOS and not Mac in general.
First,know that atomicity by itself does not insure thread safety for your class, it simply generates accessors that will set and get your properties in a thread safe way. This is a subtle distinction. To create thread safe code, you will very likely need to do much more than simply use atomic accessors.
Second, another key point to know is that your accessors can be called from background or foreground threads safely regardless of atomicity. The key here is that they must never be called from two threads simultaneously. Nor can you call the setter from one thread while simultaneously calling the getter from another, etc. How you prevent that simultaneous access depends on what tools you use.
That said, to answer your question, you can't know for sure that your accessors won't be accessed on another thread in the future. This is why thread safety is hard, and a lot of code isn't thread safe. In general, if youre making a framework or library, yeah, you can try to make your code thread safe for the purposes of "defensive programming", or you can leave it non-thread safe. The atomicity of your properties is only a small part of that. Whichever you choose, though, be sure to document it so users of your library don't have to wonder.