[C/C++]_[macOS-Windows]_[原子操作2]
来源:互联网 发布:中国不成熟的网络环境 编辑:程序博客网 时间:2024/06/10 18:20
场景
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 10000static 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] TestAtomic2017-07-11 10:26:18.165 TestObjc[744:303] foo is 12017-07-11 10:26:18.165 TestObjc[744:303] ++ OSAtomicIncrement64: 22017-07-11 10:26:18.166 TestObjc[744:303] -- OSAtomicDecrement64: 12017-07-11 10:26:18.166 TestObjc[744:303] = OSAtomicCompareAndSwap64: 642017-07-11 10:26:18.167 TestObjc[744:303] += OSAtomicAdd64: 1002017-07-11 10:26:18.167 TestObjc[744:303] -= OSAtomicAdd64: 642017-07-11 10:26:18.168 TestObjc[744:303] TestCppAtomicLibrary2017-07-11 10:26:18.168 TestObjc[744:303] foo is 12017-07-11 10:26:18.169 TestObjc[744:303] ++ OSAtomicIncrement64: 22017-07-11 10:26:18.169 TestObjc[744:303] -- OSAtomicDecrement64: 12017-07-11 10:26:18.170 TestObjc[744:303] = OSAtomicCompareAndSwap64: 642017-07-11 10:26:18.170 TestObjc[744:303] += OSAtomicAdd64: 1002017-07-11 10:26:18.171 TestObjc[744:303] -= OSAtomicAdd64: 642017-07-11 10:26:18.171 TestObjc[744:303] Begin CAtomic2017-07-11 10:26:18.259 TestObjc[744:303] End CAtomic2017-07-11 10:26:18.260 TestObjc[744:303] Begin CppAtomic2017-07-11 10:26:18.360 TestObjc[744:303] End CAtomic
参考
atomic
Windows 原子操作
阅读全文
0 0
- [C/C++]_[macOS-Windows]_[原子操作2]
- [C/C++]_[初级]_[原子操作]
- C#_位操作
- c#_xml读写_操作_实例
- [Object-C]_[C/C++]_[集合操作对比]
- [Object-C]_[C/C++]_[日期时间操作对比]
- c++_操作符重载
- [Windows]_[C/C++]_[如何调试子进程]
- c+_+
- [MD5]_[Windows-macOS]_[计算文件的MD5]
- C/C++-------------__sync_fetch_and_add 原子操作------------------
- [C/C++标准库]_[初级]_[集合操作]
- C语言_初成长_操作符和表达式
- 9.1 内核同步方法_原子操作
- C/C++_
- C/C++_扫雷
- C#_对内存的操作(转)
- C语言_文件的操作
- OC语言学习01-类与对象
- mysql --时间日期函数总结
- k8s volume plugin FlexVolume 开发
- bootstrap-table 搜索框 中文乱码问题解决
- sails开发之配置MongoDB数据库连接
- [C/C++]_[macOS-Windows]_[原子操作2]
- C# 使用SSL访问webservice(自用)
- 利用js实现 禁用浏览器后退
- 趟过(1062
- Activity生命周期
- 设计模式
- Eclipse 异常处理记录
- jq判断视频播放结束,ended
- 关于Android6.0以上系统的权限问题