Objc的底层并发API(转)
- + (UIColor *)boringColor;
- {
- static UIColor *color;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- color = [UIColor colorWithRed:0.380f green:0.376f blue:0.376f alpha:1.000f];
- });
- return color;
- }
- - (void)foo
- {
- double delayInSeconds = 2.0;
- dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t) (delayInSeconds * NSEC_PER_SEC));
- dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
- [self bar];
- });
- }
- - (id)init;
- {
- self = [super init];
- if (self != nil) {
- NSString *label = [NSString stringWithFormat:@"%@.isolation.%p", [self class], self];
- self.isolationQueue = dispatch_queue_create([label UTF8String], 0);
- label = [NSString stringWithFormat:@"%@.work.%p", [self class], self];
- self.workQueue = dispatch_queue_create([label UTF8String], 0);
- }
- return self;
- }
- - (void)setCount:(NSUInteger)count forKey:(NSString *)key
- {
- key = [key copy];
- dispatch_async(self.isolationQueue, ^(){
- if (count == 0) {
- [self.counts removeObjectForKey:key];
- } else {
- self.counts[key] = @(count);
- }
- });
- }
- - (NSUInteger)countForKey:(NSString *)key;
- {
- __block NSUInteger count;
- dispatch_sync(self.isolationQueue, ^(){
- NSNumber *n = self.counts[key];
- count = [n unsignedIntegerValue];
- });
- return count;
- }
- self.isolationQueue = dispatch_queue_create([label UTF8String], DISPATCH_QUEUE_CONCURRENT);
- - (void)setCount:(NSUInteger)count forKey:(NSString *)key
- {
- key = [key copy];
- dispatch_barrier_async(self.isolationQueue, ^(){
- if (count == 0) {
- [self.counts removeObjectForKey:key];
- } else {
- self.counts[key] = @(count);
- }
- });
- }
- dispatch_queue_t queueA; // assume we have this
- dispatch_sync(queueA, ^(){
- dispatch_sync(queueA, ^(){
- foo();
- });
- });
- dispatch_queue_t queueA; // assume we have this
- dispatch_queue_t queueB; // assume we have this
- dispatch_sync(queueA, ^(){
- foo();
- });
- void foo(void)
- {
- dispatch_sync(queueB, ^(){
- bar();
- });
- }
- void bar(void)
- {
- dispatch_sync(queueA, ^(){
- baz();
- });
- }
- dispatch_queue_t queueA; // assume we have this
- dispatch_async(queueA, ^(){
- dispatch_async(queueA, ^(){
- foo();
- });
- });
- - (void)processImage:(UIImage *)image completionHandler:(void(^)(BOOL success))handler;
- {
- dispatch_async(self.isolationQueue, ^(void){
- // do actual processing here
- dispatch_async(self.resultQueue, ^(void){
- handler(YES);
- });
- });
- }
- for (size_t y = 0; y < height; ++y) {
- for (size_t x = 0; x < width; ++x) {
- // Do something with x and y here
- }
- }
- dispatch_apply(height, dispatch_get_global_queue(0, 0), ^(size_t y) {
- for (size_t x = 0; x < width; x += 2) {
- // Do something with x and y here
- }
- });
- dispatch_group_t group = dispatch_group_create();
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_group_async(group, queue, ^(){
- // Do something that takes a while
- [self doSomeFoo];
- dispatch_group_async(group, dispatch_get_main_queue(), ^(){
- self.foo = 42;
- });
- });
- dispatch_group_async(group, ^(){
- // Do something else that takes a while
- [self doSomeBar];
- dispatch_group_async(group, dispatch_get_main_queue(), ^(){
- self.bar = 1;
- });
- });
- // This block will run once everything above is done:
- dispatch_group_notify(group, dispatch_get_main_queue(), ^(){
- NSLog(@"foo: %d", self.foo);
- NSLog(@"bar: %d", self.bar);
- });
- - (void)withGroup:(dispatch_group_t)group performBlock:(dispatch_block_t)block
- {
- if (group == NULL) {
- [self performBlock:block];
- } else {
- dispatch_group_enter(group);
- [self performBlock:^(){
- block();
- dispatch_group_leave(group);
- }];
- }
- }
- + (void)withGroup:(dispatch_group_t)group
- sendAsynchronousRequest:(NSURLRequest *)request
- queue:(NSOperationQueue *)queue
- completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler
- {
- if (group == NULL) {
- [self sendAsynchronousRequest:request
- queue:queue
- completionHandler:handler];
- } else {
- dispatch_group_enter(group);
- [self sendAsynchronousRequest:request
- queue:queue
- completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
- handler(response, data, error);
- dispatch_group_leave(group);
- }];
- }
- }
- NSRunningApplication *mail = [NSRunningApplication
- runningApplicationsWithBundleIdentifier:@"com.apple.mail"];
- if (mail == nil) {
- return;
- }
- pid_t const pid = mail.processIdentifier;
- self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, pid,
- DISPATCH_PROC_EXIT, DISPATCH_TARGET_QUEUE_DEFAULT);
- dispatch_source_set_event_handler(self.source, ^(){
- NSLog(@"Mail quit.");
- });
- dispatch_resume(self.source);
- NSURL *directoryURL; // assume this is set to a directory
- int const fd = open([[directoryURL path] fileSystemRepresentation], O_EVTONLY);
- if (fd < 0) {
- char buffer[80];
- strerror_r(errno, buffer, sizeof(buffer));
- NSLog(@"Unable to open \"%@\": %s (%d)", [directoryURL path], buffer, errno);
- return;
- }
- dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd,
- DISPATCH_VNODE_WRITE | DISPATCH_VNODE_DELETE, DISPATCH_TARGET_QUEUE_DEFAULT);
- dispatch_source_set_event_handler(source, ^(){
- unsigned long const data = dispatch_source_get_data(source);
- if (data & DISPATCH_VNODE_WRITE) {
- NSLog(@"The directory changed.");
- }
- if (data & DISPATCH_VNODE_DELETE) {
- NSLog(@"The directory has been deleted.");
- }
- });
- dispatch_source_set_cancel_handler(source, ^(){
- close(fd);
- });
- self.source = source;
- dispatch_resume(self.source);
- dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
- 0, 0, DISPATCH_TARGET_QUEUE_DEFAULT);
- dispatch_source_set_event_handler(source, ^(){
- NSLog(@"Time flies.");
- });
- dispatch_time_t start
- dispatch_source_set_timer(source, DISPATCH_TIME_NOW, 5ull * NSEC_PER_SEC,
- 100ull * NSEC_PER_MSEC);
- self.source = source;
- dispatch_resume(self.source);
0: HTTP/1.1 200 OK\r\nDate: Mon, 23 May 2005 22:38
1: :34 GMT\r\nServer: Apache/1.3.3.7 (Unix) (Red-H
2: at/Linux)\r\nLast-Modified: Wed, 08 Jan 2003 23
3: :11:55 GMT\r\nEtag: "3f80f-1b6-3e1cb03b"\r\nCon
4: tent-Type: text/html; charset=UTF-8\r\nContent-
5: Length: 131\r\nConnection: close\r\n\r\n<html>\r
6: \n<head>\r\n <title>An Example Page</title>\r\n
7: </head>\r\n<body>\r\n Hello World, this is a ve
dispatch_data_t a; // Assume this hold some valid data
dispatch_data_t b; // Assume this hold some valid data
dispatch_data_t c = dispatch_data_create_concat(a, b);
dispatch_data_apply(c, ^(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {
fprintf(stderr, "region with offset %zu, size %zu\n", offset, size);
return true;
});
dispatch_io_t dispatch_io_create(dispatch_io_type_t type, dispatch_fd_t fd,
dispatch_queue_t queue, void (^cleanup_handler)(int error));
_isolation = dispatch_queue_create([[self description] UTF8String], 0);
_nativeSocket = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in sin = {};
sin.sin_len = sizeof(sin);
sin.sin_family = AF_INET6;
sin.sin_port = htons(port);
sin.sin_addr.s_addr= INADDR_ANY;
int err = bind(result.nativeSocket, (struct sockaddr *) &sin, sizeof(sin));
NSCAssert(0 <= err, @"");
_eventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, _nativeSocket, 0, _isolation);
dispatch_source_set_event_handler(result.eventSource, ^{
acceptConnection(_nativeSocket);
});
typedef union socketAddress {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} socketAddressUnion;
socketAddressUnion rsa; // remote socket address
socklen_t len = sizeof(rsa);
int native = accept(nativeSocket, &rsa.sa, &len);
if (native == -1) {
// Error. Ignore.
return nil;
}
_remoteAddress = rsa;
_isolation = dispatch_queue_create([[self description] UTF8String], 0);
_channel = dispatch_io_create(DISPATCH_IO_STREAM, native, _isolation, ^(int error) {
NSLog(@"An error occured while listening on socket: %d", error);
});
//dispatch_io_set_high_water(_channel, 8 * 1024);
dispatch_io_set_low_water(_channel, 1);
dispatch_io_set_interval(_channel, NSEC_PER_MSEC * 10, DISPATCH_IO_STRICT_INTERVAL);
socketAddressUnion lsa; // remote socket address
socklen_t len = sizeof(rsa);
getsockname(native, &lsa.sa, &len);
_localAddress = lsa;
如果我们想要设置SO_KEEPALIVE(如果我们使用了HTTP的keep-alive等级),我们需要在调用dispatch_io_create前这么做。 创建好I/O通道后,我们可以设置读取处理程序:
dispatch_io_read(_channel, 0, SIZE_MAX, _isolation, ^(bool done, dispatch_data_t data, int error){
if (data != NULL) {
if (_data == NULL) {
_data = data;
} else {
_data = dispatch_data_create_concat(_data, data);
}
[self processData];
}
});
uint64_t dispatch_benchmark(size_t count, void (^block)(void));
size_t const objectCount = 1000;
uint64_t n = dispatch_benchmark(10000, ^{
@autoreleasepool {
id obj = @42;
NSMutableArray *array = [NSMutableArray array];
for (size_t i = 0; i < objectCount; ++i) {
[array addObject:obj];
}
}
});
NSLog(@"-[NSMutableArray addObject:] : %llu ns", n);
-[NSMutableArray addObject:] : 31803 ns
curl "http://opensource.apple.com/source/libdispatch/libdispatch-84.5/man/dispatch_benchmark.3?txt"
| /usr/bin/groffer --tty -T utf8
void * sharedBuffer(void)
{
static void * buffer;
if (buffer == NULL) {
void * newBuffer = calloc(1, 1024);
if (!OSAtomicCompareAndSwapPtrBarrier(NULL, newBuffer, &buffer)) {
free(newBuffer);
}
}
return buffer;
}
@interface MyTableViewCell : UITableViewCell
@property (readonly, nonatomic, copy) NSDictionary *amountAttributes;
@end
@implementation MyTableViewCell
{
NSDictionary *_amountAttributes;
}
- (NSDictionary *)amountAttributes;
{
if (_amountAttributes == nil) {
static __weak NSDictionary *cachedAttributes = nil;
static OSSpinLock lock = OS_SPINLOCK_INIT;
OSSpinLockLock(&lock);
_amountAttributes = cachedAttributes;
if (_amountAttributes == nil) {
NSMutableDictionary *attributes = [[self subtitleAttributes] mutableCopy];
attributes[NSFontAttributeName] = [UIFont fontWithName:@"ComicSans" size:36];
attributes[NSParagraphStyleAttributeName] = [NSParagraphStyle defaultParagraphStyle];
_amountAttributes = [attributes copy];
cachedAttributes = _amountAttributes;
}
OSSpinLockUnlock(&lock);
}
return _amountAttributes;
}
Objc的底层并发API(转)的更多相关文章
- 【转】Objc的底层并发API
本文由webfrogs译自objc.io,原文作者Daniel Eggert.转载请注明出处! 小引 本篇英文原文所发布的站点objc.io是一个专门为iOS和OS X开发者提供的深入讨论技术的平台, ...
- Objc的底层并发API
本文由webfrogs译自objc.io,原文作者Daniel Eggert.转载请注明出处! 小引 本篇英文原文所发布的站点objc.io是一个专门为iOS和OS X开发者提供的深入讨论技术的平台, ...
- IOS 多线程04-GCD详解 底层并发 API
注:本人是翻译过来,并且加上本人的一点见解. 前言 想要揭示出表面之下深层次的一些可利用的方面.这些底层的 API 提供了大量的灵活性,随之而来的是大量的复杂度和更多的责任.在我们的文章常见的后台实践 ...
- 底层并发APIs_源自objc.io
本文由webfrogs译自objc.io,原文作者Daniel Eggert. 小引 本篇英文原文所发布的站点objc.io是一个专门为iOS和OS X开发者提供的深入讨论技术的平台,文章含金量很 ...
- 如何精确地测量java对象的大小-底层instrument API
转载: 如何精确地测量java对象的大小-底层instrument API 关于java对象的大小测量,网上有很多例子,大多数是申请一个对象后开始做GC,后对比前后的大小,不过这样,虽然说这样测量对象 ...
- 驰骋工作流引擎-底层开发API 说明文档
驰骋工作引擎-底层开发API 登录与门户API 首先要进行代码集成与组织机构的集成 其次在自己的系统登录界面,登录成功后要执行ccbpm的框架登录. 所谓的登录就是调用ccbpm的登录接口,如左边的代 ...
- Effective Modern C++:07并发API
C++11的志伟功勋之一,就是将并发融入了语言和库中,因此在C++的历史上,程序员可以首次跨越所有平台撰写具有标准行为的多线程程序. 35:优先选用基于任务而非基于线程的程序设计 如果需要以异步的方式 ...
- java并发api总结
开发十年,就只剩下这套架构体系了! >>> 1.java.util.concurrent包 1.1 Executors Executor:接口,仅有一个方法为execute(Ru ...
- 【转】Objective-C并发编程:API和挑战
并发指的是在同一时间运行多个任务.在单核CPU的情况下,它通过分时的方式实现,如果有多个CPU可用,则是真正意义上的多个任务“并行”执行了. OS X和iOS提供了多个API支持并发编程.每个API都 ...
随机推荐
- debian 7 stable 不能编译android源码
rebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8-linaro/bin/arm-linux-androideabi-gcc: /lib/x86_ ...
- App架构经验总结
作者:李纪钢,网名 Keegan小钢,博客地址:http://keeganlee.me.目前在广州日报新媒体有限公司,负责移动产品的研发工作. 关于:本文整理自CSDN架构主题月子活动金牌架构师微课堂 ...
- BZOJ 5313: 新Fib数列
打表找规律 #include<cstdio> using namespace std; int F[20]={0,1,1,2,3,0,3,3,1,4,0,4,4,3,2,0,2,2,4,1 ...
- python基础学习笔记——字典
字典(Dictionary) 字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 { ...
- struts2对properties资源的处理
struts2对properties资源的处理 做了一些功能增强 包括: 可以读取项的描述 可以读取项所在的行号,文件路径等 实现方式 继承了java的java.util.Properties实现了一 ...
- js 判断ie的版本号
//IE6判断: var isIE6 = !!window.ActiveXObject && !window.XMLHttpRequest; //或者: if(navigator.us ...
- Golang遇到的问题记录
1,windows cmd 结束输入问题 func main() { counts := make(map[string]int) countLines(os.Stdin, counts) fmt.P ...
- Hibernate框架简述(转)
转自:http://www.cnblogs.com/eflylab/archive/2007/01/09/615338.html Hibernate的核心组件在基于MVC设计模式的JAVA WEB应用 ...
- 【bzoj3439】Kpm的MC密码 可持久化Trie树
题目描述 背景 想Kpm当年为了防止别人随便进入他的MC,给他的PC设了各种奇怪的密码和验证问题(不要问我他是怎么设的...),于是乎,他现在理所当然地忘记了密码,只能来解答那些神奇的身份验证问题了. ...
- 【反省】qqxt第一场考试
我太蒟了 qwq 这是第一条 2:考试别水群,别乱fake,特别是要避免出现不顾考试时间每件事fake十分钟的情况 3:少想多写,虽然说写数据结构之前一定要先想好但是别墨迹. 4:保持对考试的敬畏,别 ...