底层并发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 ...
随机推荐
- day2之爬取拉勾网
认证流程 浏览器清空cookies 步骤一 访问拉勾网网站 https://www.lagou.com/ 做了些什么: 以get方式请求"https://www.lagou.com/&qu ...
- 【HDOJ5979】Convex(三角函数)
题意:n个点在一个半径为R的圆上,给出这n个点顺时针的夹角差值,求这n个点的凸包面积 n<=10,R<=10 思路:S=1/2*sinθ*a*b 角度转弧度再用sin C++有点小毛病,叫 ...
- 【Eclipse】eclipse部署web项目至本地的tomcat但在webapps中找不到
clipse部署web项目至本地的tomcat但在webapps中找不到 1.发现问题 在我的 eclipse 中有个Dynamic Web Project(动态web项目),在本地的 tomcat ...
- dos中定义变量与获取常见的引用变量以及四则运算、备份文件(set用法)
在dos中使用set定义变量: set a=8 (注意等号两边没有空格) 引用变量如: echo %a% 将打印a的值 (%a%是获取变量a的值) dos中 ...
- linux 内核源码arch/ 目录的前世今生
历史的痕迹:在最新的linux-2.6.31/arch/arm/文件夹下,仍然保留Linux最初向ARM处理器移植的痕迹,最初的移植由黑客完成,在老的移植的代码文件的头部保留着黑客的名字:最初的ARM ...
- django搭建开发环境
1.安装python,安装pip,添加环境变量 2.使用虚拟环境Virtualenv,下载virtualenv解压,进入到此目录,cmd运行python setup.py install(或直接打开c ...
- AC日记——[网络流24题]方格取数问题 cogs 734
734. [网络流24题] 方格取数问题 ★★☆ 输入文件:grid.in 输出文件:grid.out 简单对比时间限制:1 s 内存限制:128 MB «问题描述: 在一个有m*n ...
- npm 安装vue-cli
TIP:win10下安装,使用管理员身份进行,否则会有权限限制. 1,安装完成node,node有自带的npm,可以直接在cmd中,找到nodeJs安装的路径下,进行命令行全局安装vue-cli.(n ...
- Idea配置Tomcat以及maven
配置Tamcat Run-->Edit Configurations +-->如果列表里没有tomcat-->点击33 items more irrelevant继续寻找--> ...
- 【Linux】在虚拟机上安装ubuntu
虚拟机安装步骤 参考:http://www.cnblogs.com/sxdcgaq8080/p/7466529.html 在安装ubuntu系统之前,当然是下载一个ubuntu的iso镜像在本地啦. ...