底层并发APIs_源自objc.io
- + (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;
}
底层并发APIs_源自objc.io的更多相关文章
- 【转】Objc的底层并发API
本文由webfrogs译自objc.io,原文作者Daniel Eggert.转载请注明出处! 小引 本篇英文原文所发布的站点objc.io是一个专门为iOS和OS X开发者提供的深入讨论技术的平台, ...
- Objc的底层并发API
本文由webfrogs译自objc.io,原文作者Daniel Eggert.转载请注明出处! 小引 本篇英文原文所发布的站点objc.io是一个专门为iOS和OS X开发者提供的深入讨论技术的平台, ...
- Objc的底层并发API(转)
本文由webfrogs译自objc.io,原文作者Daniel Eggert. 小引 本篇英文原文所发布的站点objc.io是一个专门为iOS和OS X开发者提供的深入讨论技术的平台,文章含金量很 ...
- 关于objc.io
推荐一个特别棒的项目:objc.io 原版地址:http://www.objc.io/ 中国版地址:http://objccn.io/ 欢迎大家前去学习,如果你有不错的东西,也欢迎跟帖分享.
- 理论铺垫:阻塞IO、非阻塞IO、IO多路复用/事件驱动IO(单线程高并发原理)、异步IO
完全来自:http://www.cnblogs.com/alex3714/articles/5876749.html 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同 ...
- IOS 多线程04-GCD详解 底层并发 API
注:本人是翻译过来,并且加上本人的一点见解. 前言 想要揭示出表面之下深层次的一些可利用的方面.这些底层的 API 提供了大量的灵活性,随之而来的是大量的复杂度和更多的责任.在我们的文章常见的后台实践 ...
- MySQL并发调优和IO调优
一.myisam的IO调优1.myisam通常在每次写入后把索引的改变刷写到磁盘上.所以批处理通常会更快点.做到这点,可以通过LOCK TABLES,他可以把写入控制到对表解锁.还可以用delay_k ...
- 3高并发server:多路IO之epoll
1 epoll epoll是Linux下多路复用IO接口select/poll的增强版本号,它能显著提高程序在大量并.发连接中仅仅有少量活跃的情况下的系统CPU利用率,由于它会复用文件描写叙述符 ...
- day33 网络编程之线程,并发以及selectors模块io多路复用
io多路复用 selectors模块 概要: 并发编程需要掌握的知识点: 开启进程/线程 生产者消费者模型!!! GIL全局解释器锁(进程与线程的区别和应用场景) 进程池线程池 IO模型(理论) 1 ...
随机推荐
- uva 11916 解模方程a^x=b (mod n)
Emoogle Grid You have to color an M x N ( 1M, N108) two dimensional grid. You will be provided K ...
- Redis命令行之Zset
一.Redis之Zset简介 1. 有序集合Zset是String类型的有序集合. 2. Zset中每个元素都会关联一个double类型的分数值,redis通过分数值来为集合中所有成员进行从小到大排序 ...
- git(三):第一次github了解使用
第一次使用github,看了一下使用说明,创建第一个repository,以后还要多学习. 一.Github创建一个新仓库 ······Creat a new repository 创建一个新仓库,点 ...
- T2597 团伙 codevs
http://codevs.cn/problem/2597/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 1920年的芝加 ...
- mongDB的常用操作总结
目录 常用查询: 查询一条数据 查询子元素集合:image.id gte: 大于等于,lte小于等于... 查询字段不存在的数据not 查询数量: 常用更新 更新第一条数据的一个字段: 更新一条数据的 ...
- 面试题:oracle数据库行转列的问题
今天我一个学弟问了一个面试题: 有表A,结构如下:A: p_ID p_Num s_id1 10 011 12 022 8 013 11 013 8 03其中:p_ID为产品ID,p_Num为产品库存量 ...
- uibutton去掉点击后背景有阴影的方法
1,将normal和highlight两种方式都设置上图片即可 UIButton *goback = [[UIButton alloc]initWithFrame:CGRectMake(5.0f, 5 ...
- Redhat7/centOs7 安装配置python3.6.5
centos默认安装python2,设置py2和py3并存的方法如下: sudo yum install openssl-devel -y sudo yum install zlib-devel -y ...
- LVM创建
LVM介绍 PV(Physical Volume) - 物理卷 物理卷在逻辑卷管理中处于最底层,它可以是实际物理硬盘上的分区,也可以是整个物理硬盘,也可以是raid设备 VG(Volume Group ...
- 使用 Unicode 编码
面向公共语言执行库的应用程序使用编码将字符表示形式从本机字符方案(Unicode)映射为其它方案. 应用程序使用解码将字符从非本机方案(非 Unicode)映射为本机方案. System.Text 命 ...