macOS-Windows-C/C++原子操作

2017-07-12 11:10:08来源:http://blog.csdn.net/infoworld/article/details/74942005作者:CSDN博客人点击

场景

1.原子操作一般用在多线程执行的逻辑里, 比如统计业务个数 ++count, 或者下载文件个数,下载大小, 设置对象状态等. 如果不用原子操作, 那么可能在并发情况下, 原本的事务指令A会被事务指令2抢占而导致出现数据被覆盖.


说明


1.macOS下提供了<libkern/OSAtomic.h>
来处理 C 方式的原子操作. 如果是object-c方式的原子属性可以使用关键字atomic
.



2.C++11(vs2012以上)也提供了方便使用可移植的Atomic Library
,


例子
#include <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>
#include <time.h>
#include <vector>
#include <atomic>
#include <algorithm>
#include <pthread.h>
#include <libkern/OSAtomic.h>
void TestAtomic(){
NSLog(@"TestAtomic");
volatile int64_t foo = 1;
NSLog(@"foo is %lld",foo);
//++
OSAtomicIncrement64(&foo);
NSLog(@"++ OSAtomicIncrement64: %lld",foo);
//--
OSAtomicDecrement64(&foo);
NSLog(@"-- OSAtomicDecrement64: %lld",foo);
//=
OSAtomicCompareAndSwap64(foo, 64, &foo);
NSLog(@"= OSAtomicCompareAndSwap64:%lld",foo);
// +=
OSAtomicAdd64(36, &foo);
NSLog(@"+= OSAtomicAdd64:%lld",foo);
// -=
OSAtomicAdd64(-36, &foo);
NSLog(@"-= OSAtomicAdd64:%lld",foo);
}
void TestCppAtomicLibrary(){
NSLog(@"TestCppAtomicLibrary");
std::atomic<int64_t> foo(1);
NSLog(@"foo is %lld",foo.load());
//++
++foo;
NSLog(@"++ OSAtomicIncrement64: %lld",foo.load());
//--
--foo;
NSLog(@"-- OSAtomicDecrement64: %lld",foo.load());
//=
foo = 64;
NSLog(@"= OSAtomicCompareAndSwap64:%lld",foo.load());
// +=
foo+=36;
NSLog(@"+= OSAtomicAdd64:%lld",foo.load());
// -=
foo-=36;
NSLog(@"-= OSAtomicAdd64:%lld",foo.load());
}
#define THREAD_COUNT 100
#define FOR_NUMBER 10000
static volatile int32_t count = 0;
static pthread_mutex_t mutex;
static pthread_cond_t cond;
static volatile int64_t foo = 1;
static std::atomic<int64_t> foo1(1);
void* RunCAtomic(void*){
for(int i = 0; i< FOR_NUMBER;++i){
OSAtomicIncrement64(&foo); // fail if ++foo
OSAtomicAdd64(36, &foo);
}
for(int i = 0; i< FOR_NUMBER;++i){
OSAtomicDecrement64(&foo);
OSAtomicAdd64(-36, &foo);
}
OSAtomicIncrement32(&count);
if(OSAtomicCompareAndSwap32(THREAD_COUNT, 0, &count)){
assert(count == 0);
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
void* RunCppAtomic(void*){
for(int i = 0; i< FOR_NUMBER;++i){
++foo1;
foo1+=36;
}
for(int i = 0; i< FOR_NUMBER;++i){
--foo1;
foo1-=36;
}
OSAtomicIncrement32(&count);
if(OSAtomicCompareAndSwap32(THREAD_COUNT, 0, &count)){
assert(count == 0);
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main(int argc, const char * argv[])
{
NSAutoreleasePool* pool = [NSAutoreleasePool new];
TestAtomic();
TestCppAtomicLibrary();
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_attr_t att;
pthread_attr_init(&att);
pthread_attr_setdetachstate(&att, PTHREAD_CREATE_JOINABLE);
NSLog(@"Begin CAtomic");
for(int i = 0; i < THREAD_COUNT;++i){
pthread_t t;
pthread_create(&t,&att,RunCAtomic,NULL);
}
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
assert(foo == 1);
NSLog(@"End CAtomic");
NSLog(@"Begin CppAtomic");
for(int i = 0; i < THREAD_COUNT;++i){
pthread_t t;
pthread_create(&t,&att,RunCppAtomic,NULL);
}
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
assert(foo1.load() == 1);
NSLog(@"End CAtomic");
[pool drain];
return 0;
}

输出:


2017-07-11 10:26:18.162 TestObjc[744:303] TestAtomic
2017-07-11 10:26:18.165 TestObjc[744:303] foo is 1
2017-07-11 10:26:18.165 TestObjc[744:303] ++ OSAtomicIncrement64: 2
2017-07-11 10:26:18.166 TestObjc[744:303] -- OSAtomicDecrement64: 1
2017-07-11 10:26:18.166 TestObjc[744:303] = OSAtomicCompareAndSwap64:64
2017-07-11 10:26:18.167 TestObjc[744:303] += OSAtomicAdd64:100
2017-07-11 10:26:18.167 TestObjc[744:303] -= OSAtomicAdd64:64
2017-07-11 10:26:18.168 TestObjc[744:303] TestCppAtomicLibrary
2017-07-11 10:26:18.168 TestObjc[744:303] foo is 1
2017-07-11 10:26:18.169 TestObjc[744:303] ++ OSAtomicIncrement64: 2
2017-07-11 10:26:18.169 TestObjc[744:303] -- OSAtomicDecrement64: 1
2017-07-11 10:26:18.170 TestObjc[744:303] = OSAtomicCompareAndSwap64:64
2017-07-11 10:26:18.170 TestObjc[744:303] += OSAtomicAdd64:100
2017-07-11 10:26:18.171 TestObjc[744:303] -= OSAtomicAdd64:64
2017-07-11 10:26:18.171 TestObjc[744:303] Begin CAtomic
2017-07-11 10:26:18.259 TestObjc[744:303] End CAtomic
2017-07-11 10:26:18.260 TestObjc[744:303] Begin CppAtomic
2017-07-11 10:26:18.360 TestObjc[744:303] End CAtomic
参考


atomic
Windows 原子操作


最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台