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

iOS并发编程

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for 姚东旭 姚东旭
January 17, 2013

 iOS并发编程

iOS平台并发编程介绍

Avatar for 姚东旭

姚东旭

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⽇日星期四