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都 ...
随机推荐
- HBase0.94.2-cdh4.2.0需求评估测试报告1.0之五
根据以上图分析得出以下结论: 1. 在上面的hbase配置下,顺序和随机写记录(每条记录1K),每写入86-87M(大小可配)左右数据生成一个磁盘文件(store file). 2. 在上面的hbas ...
- HDU 3861 The King’s Problem 强连通分量 最小路径覆盖
先找出强连通分量缩点,然后就是最小路径覆盖. 构造一个二分图,把每个点\(i\)拆成两个点\(X_i,Y_i\). 对于原图中的边\(u \to v\),在二分图添加一条边\(X_u \to Y_v\ ...
- 《小团团团队》【Alpha】Scrum Meeting 3
项目 内容 课程名 软件工程 作业链接地址 Github地址 团队名称 小团团团队 具体目标 1.掌握软件测试基础技术:2.学习迭代式增量软件开发过程(Scrum) 1.1前言 第三天 时间: 201 ...
- luogu2394 yyy loves Chemistry I
练习 #include <iostream> #include <cstdio> using namespace std; long double a; int main(){ ...
- Apache 根据不同的端口 映射不同的站点
以前,在本地新建个项目,总是在Apache的htdocs目录下新建个项目目录,今年弄了个别人写好的网站源码,因为该系统的作者假定网站是放在根目录的,放在二级目录下会出错.所以无奈,只能想办法,根据端口 ...
- python列出指定目录下的所有目录和文件
import os import docx def scanfile(rootdir): result = [] for f in os.walk(rootdir): for files in f[2 ...
- Nginx报 No input file specified. 的问题解决之路 转
https://m.aliyun.com/yunqi/articles/34240 今天接手公司的一个项目,照例将项目clone下来,配置本地host,nginx,然后访问. 怎么回事?迅速在php的 ...
- kmp-模板-hd-1711
p数组记录的是当该位置上失配的时候,跳到第几个进行继续匹配: /* 题意:给两个数串,求模板串第一此出现在源串中的位置,开头的位置:没有输出-1: 算法:kmp 先对字符串进行自匹配: 然后串间匹配: ...
- localStorage的用法
1.在HTML5中,本地存储是一个window的属性,包括localStorage和sessionStorage,前者是一直存在本地的,后者是伴随着session,窗口一旦关闭就消失了.二者用法完全相 ...
- BZOJ1297 [SCOI2009]迷路 【矩阵优化dp】
题目 windy在有向图中迷路了. 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. 现在给出该有向图,你能告诉windy总共有多少种不同的路径吗? 注意: ...