(转: http://blog.csdn.net/a21064346/article/details/8076972)
#import<libkern/OSAtomic.h>
导入这个文件,可以调用里面的函数,来保证变量的数值。
/*! @header
* These are the preferred versions of the atomic andsynchronization operations.
* Their implementation is customized at boot time for the platform, including
* late-breaking errata fixes as necessary. They are thread safe.
*
* WARNING: all addresses passed to these functions must be "naturally aligned",
* i.e. * <code>int32_t</code> pointers must be 32-bit aligned (low 2 bits of
* address are zeroes), and <code>int64_t</code> pointers must be 64-bit aligned
* (low 3 bits of address are zeroes.)
*
* Note that some versions of the atomic functions incorporate memory barriers
* and some do not. Barriers strictly order memory access on weakly-ordered
* architectures such as PPC. All loads and stores that appear (in sequential
* program order) before the barrier are guaranteed to complete before any
* load or store that appears after the barrier.
*
* On a uniprocessor system, the barrier operation is typically a no-op. On a
* multiprocessor system, the barrier can be quite expensive on some platforms,
* such as PPC.
(这段话高速我们,如果是一个多处理器的系统,运用OSATOMIC.h是显得非常有价值的。确实,因为这个东西就是为了在多线程中保证数据不会错乱,得到的数值是你最想得到的那一个,尽管它在随时变化)
*
* Most code should use the barrier functions to ensure that memory shared between
* threads is properly synchronized. For example, if you want to initialize
* a shared data structure and then atomically increment a variable to indicate
* that the initialization is complete, you must use {@link OSAtomicIncrement32Barrier}
* to ensure that the stores to your data structure complete before the atomic
* increment.
*
* Likewise, the consumer of that data structure must use {@link OSAtomicDecrement32Barrier},
* in order to ensure that their loads of the structure are not executed before
* the atomic decrement. On the other hand, if you are simply incrementing a global
* counter, then it is safe and potentially faster to use {@link OSAtomicIncrement32}.
*
* If you are unsure which version to use, prefer the barrier variants as they are
* safer.
*
* The spinlock and queue operations always incorporate a barrier.
*
* For the kernel-space version of this header, see
* {@link //apple_ref/doc/header/OSAtomic.h OSAtomic.h (Kernel Framework)}
*
* @apiuid //apple_ref/doc/header/user_space_OSAtomic.h
*/
(这里说明的是 如何使用这些函数,要求格式的一一对应。下面取一个指针的格式来进行举例)
ps:因为函数过多,具体的一些其他函数,你可以自己取查看OSATOMIC.h
/*! @abstract Compare and swap pointers.
@discussion
This function compares the pointer stored in <code>__oldValue</code> to the pointer
in the memory location referenced by <code>__theValue</code>. If the pointers
match, this function stores the pointer from <code>__newValue</code> into
that memory location atomically.
@result Returns TRUE on a match, FALSE otherwise.
*/
bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue )
- + (ABAddressBook *) sharedAddressBook
- {
- static ABAddressBook * volatile __shared = nil;
- if ( __shared == nil )
- {
- ABAddressBook * tmp = [[ABAddressBook alloc] init];
- if ( OSAtomicCompareAndSwapPtr(nil, tmp, (void * volatile *)&__shared) == false )
- [tmp release];
- }
- return ( __shared );
- }
上面一段代码 是创建一个 ABAddressBook的单例,为了保证在 调用shareAddressBook的时候,内存中只有一个且内存地址唯一(也就是说,怕其他线程访问到这个函数,同时进行访问这个单例)
volatile的作用是 每次取得数值得方式 是直接从内存中读取。(具体见 blog中volatile的转载)
目前本人使用的方法中,保证单例的 安全,类似做法如下
- + (ILSCMPersistenceManage *)sharedInstance {
- @synchronized ([ILSCMPersistenceManage class]) {
- if (__sharedInstance) {
- return __sharedInstance;
- }
- __sharedInstance = [[ILSCMPersistenceManage alloc] init];
- return __sharedInstance;
- }
- }
至于两者的区别,个人总结:
前者:更区域数据的底层,从更深层来进行对 单例的保护,而且不仅仅是作用于指针,还有其他的数据格式。并且它并没有去阻断 其他线程来对 函数的访问
后者:加锁,对代码的执行效率与前者相比要低一些。如果运用在其他数据,而这个数据被更新的速度很快,那么效率就很差了。