Upgrade to Pro — share decks privately, control downloads, hide ads and more …

iOS并发编程

姚东旭
January 17, 2013

 iOS并发编程

iOS平台并发编程介绍

姚东旭

January 17, 2013
Tweet

Other Decks in Programming

Transcript

  1. • Concurrency is about dealing with lots of things at

    once.Parallelism is about doing lots of things at once. • Not the same, but related. • One is about structure, one is about execution. • Concurrency provides a way to structure a solution to solve a problem that may (but not necessarily) be parallelizable. 13年1月17⽇日星期四
  2. • Concurrency is about dealing with lots of things at

    once.Parallelism is about doing lots of things at once. • Not the same, but related. • One is about structure, one is about execution. • Concurrency provides a way to structure a solution to solve a problem that may (but not necessarily) be parallelizable. Concurrency is not Parallelism 13年1月17⽇日星期四
  3. • 原⽣生线程 - NSThread - POSIX Threads - NSObject •

    GCD • Operation Queue 13年1月17⽇日星期四
  4. 原⽣生线程 POSIX Threads pthread_attr_t attr; pthread_t posixThreadID; int returnVal; returnVal

    = pthread_attr_init(&attr); assert(!returnVal); returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); assert(!returnVal); int threadError = pthread_create(&posixThreadID, &attr, &PosixThreadMainRoutine, NULL); returnVal = pthread_attr_destroy(&attr); @interface PhotoUploadTask() { FILE *cfile; } 13年1月17⽇日星期四
  5. Thread 1 Thread 2 Block A Thread 3 Block B

    Thread Pool Concurrent Queue 13年1月17⽇日星期四
  6. GCD block的内存问题 __block typeof(self) bself = self; self.block = ^{

    [bself doSomething]; }; 13年1月17⽇日星期四
  7. GCD block的内存问题 __block typeof(self) bself = self; self.block = ^{

    [bself doSomething]; }; - (void)dealloc { self.block = nil; [super dealloc]; } 13年1月17⽇日星期四
  8. GCD block的内存问题 __weak typeof(self) bself = self; self.block = ^{

    [bself doSomething]; }; ⾮非ARC环境替代⽅方案 https://github.com/mikeash/MAZeroingWeakRef 13年1月17⽇日星期四
  9. GCD block的内存问题 __weak typeof(self) bself = self; self.block = ^{

    [bself doSomething]; }; ARC only ⾮非ARC环境替代⽅方案 https://github.com/mikeash/MAZeroingWeakRef 13年1月17⽇日星期四
  10. CLHttpRequest.h @interface CLHttpRequest : NSOperation @end CLRequestManager.m - (void)addHttpRequest:(CLHttpRequest *)aRequest

    { [[NSOperationQueue mainQueue] addOperation:aRequest]; } Operation Queue 13年1月17⽇日星期四
  11. NSOperation Operation Queue MyOperation.h @interface MyOperation : NSOperation @end MyOperation.m

    @implementation MyOperation - (void)main { //do anything you want } @end 13年1月17⽇日星期四
  12. NSOperation Operation Queue NSInvocationOperation NSBlockOperation MyOperation.h @interface MyOperation : NSOperation

    @end MyOperation.m @implementation MyOperation - (void)main { //do anything you want } @end 13年1月17⽇日星期四
  13. 好处 Operation Queue • OOP(官⽅方推荐) • 任务对象接⼝口⽐比较多(NSOperation) • 可以设置依赖 •

    可以设置最⼤大并发数 @interface NSOperationQueue : NSObject { - (void)addOperation:(NSOperation *)op; - (void)addOperations:(NSArray *)ops waitUntilFinished: (BOOL)wait - (void)addOperationWithBlock:(void (^)(void))block NS_AVAILABLE(10_6, 4_0); - (NSArray *)operations; - (NSUInteger)operationCount NS_AVAILABLE(10_6, 4_0); - (NSInteger)maxConcurrentOperationCount; - (void)setMaxConcurrentOperationCount:(NSInteger)cnt; - (void)setSuspended:(BOOL)b; - (BOOL)isSuspended; - (void)setName:(NSString *)n NS_AVAILABLE(10_6, 4_0); - (NSString *)name NS_AVAILABLE(10_6, 4_0); - (void)cancelAllOperations; - (void)waitUntilAllOperationsAreFinished; + (id)currentQueue NS_AVAILABLE(10_6, 4_0); + (id)mainQueue NS_AVAILABLE(10_6, 4_0); @end 13年1月17⽇日星期四
  14. @synchronized @synchronized(anObj) { // Everything between the braces is protected

    by the @synchronized directive. } 13年1月17⽇日星期四
  15. Mutex BOOL moreToDo = YES; NSLock *theLock = [[NSLock alloc]

    init]; ... while (moreToDo) { /* Do another increment of calculation */ /* until there’s no more to do. */ if ([theLock tryLock]) { /* Update display used by all threads. */ [theLock unlock]; } } 13年1月17⽇日星期四
  16. Recursive lock NSRecursiveLock *theLock = [[NSRecursiveLock alloc] init]; void MyRecursiveFunction(int

    value) { [theLock lock]; if (value != 0) { --value; MyRecursiveFunction(value); } [theLock unlock]; } MyRecursiveFunction(5); 13年1月17⽇日星期四
  17. NSConditionLock producer.m thread: id condLock = [[NSConditionLock alloc] initWithCondition:NO_DATA]; while(YES)

    { [condLock lock]; /* Add data to the queue. */ [condLock unlockWithCondition:HAS_DATA]; } consumer thread: while (YES) { [condLock lockWhenCondition:HAS_DATA]; /* Remove data from the queue. */ [condLock unlockWithCondition:(isEmpty ? NO_DATA : HAS_DATA)]; // Process the data locally. } 13年1月17⽇日星期四
  18. Read-write lock - (id)objectAtIndex:(NSUInteger)index { __block id obj; dispatch_sync(self.concurrent_queue, ^{

    obj = [self.arrayobjectAtIndex:index]}); return obj; } - (void)insertObject:(id)obj atIndex:(NSUInteger)index { dispatch_barrier_async(self.concurrent_queue, ^{ [self.array insertObject:obj atIndex:index]; }); } @end 13年1月17⽇日星期四
  19. • 不配对 • 太少 • 太多 • 顺序不对 • 死锁

    锁带来的问题 13年1月17⽇日星期四
  20. CAS int compare_and_swap (int* reg, int oldval, int newval) {

    int old_reg_val = *reg; if (old_reg_val == oldval) *reg = newval; return old_reg_val; } 13年1月17⽇日星期四
  21. ⽣生命周期 Run Loop A run loop is an event processing

    loop that you use to schedule work and coordinate the receipt of incoming events. 13年1月17⽇日星期四
  22. ⽣生命周期 Run Loop A run loop is an event processing

    loop that you use to schedule work and coordinate the receipt of incoming events. The purpose of a run loop is to keep your thread busy when there is work to do and put your thread to sleep when there is none. 13年1月17⽇日星期四
  23. - (void)skeletonThreadMain { // Set up an autorelease pool here

    if not using garbage collection. BOOL done = NO; // Add your sources or timers to the run loop and do any other setup. do { // Start the run loop but return after each source is handled. SInt32 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, YES); // If a source explicitly stopped the run loop, or if there are no // sources or timers, go ahead and exit. if((result == kCFRunLoopRunStopped) || (result == kCFRunLoopRunFinished)) done = YES; // Check for any other exit conditions here and set the // done variable as needed. } while (!done); // Clean up code here. Be sure to release any allocated autorelease pools. } 13年1月17⽇日星期四
  24. 参考资料 • http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/ Introduction/Introduction.html • https://developer.apple.com/library/mac/#documentation/Performance/Reference/ GCD_libdispatch_Ref/Reference/reference.html • http://developer.apple.com/library/ios/documentation/General/Conceptual/ ConcurrencyProgrammingGuide/

    • http://www.ibm.com/developerworks/cn/java/j-concurrent/ • http://www.ibm.com/developerworks/cn/java/j-jtp04186/ • http://msdn.microsoft.com/en-us/magazine/cc163744.aspx • http://concur.rspace.googlecode.com/hg/talk/concur.html#landing-slide • http://www.ibm.com/developerworks/cn/java/j-lo-concurrent/index.html • http://www.ibm.com/developerworks/cn/linux/l-cn-lockfree/index.html • http://en.wikipedia.org/wiki/Thread_%28computer_science%29 13年1月17⽇日星期四