Concurrency CS 442: Mobile App Development Michael Saelee - - PowerPoint PPT Presentation

concurrency
SMART_READER_LITE
LIVE PREVIEW

Concurrency CS 442: Mobile App Development Michael Saelee - - PowerPoint PPT Presentation

Concurrency CS 442: Mobile App Development Michael Saelee <lee@iit.edu> Computer Science Science note: iOS devices are now (mostly) multi-core; i.e., concurrency may allow for real performance gains! Computer Science Science but


slide-1
SLIDE 1

Concurrency

CS 442: Mobile App Development Michael Saelee <lee@iit.edu>

slide-2
SLIDE 2

Computer Science Science

note: iOS devices are now (mostly) 
 multi-core; i.e., concurrency may allow for real performance gains!

slide-3
SLIDE 3

Computer Science Science

but the more common incentive is to improve interface responsiveness i.e., by taking lengthy computations off the critical path of UI updates

slide-4
SLIDE 4

Computer Science Science

Mechanisms

  • Threads (traditional)
  • Grand Central Dispatch
  • Dispatch queues/sources
  • Operation Queues
slide-5
SLIDE 5

Computer Science Science

Threads:

  • Cocoa threads (NSThread)
  • POSIX threads
  • if you do use PThreads, spawn a single

NSThread first! (way too low level!)

slide-6
SLIDE 6

Computer Science Science

@interface NSThread : NSObject {

  • (id)initWithTarget:(id)target 


selector:(SEL)selector 


  • bject:(id)argument;
  • (void)start;

+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target 
 withObject:(id)argument; + (NSThread *)currentThread;

  • (BOOL)isMainThread;

+ (NSThread *)mainThread; + (void)sleepForTimeInterval:(NSTimeInterval)ti; + (void)exit;

  • (BOOL)isCancelled;
  • (void)cancel;

@end

slide-7
SLIDE 7

Computer Science Science

@interface NSObject (NSThreadPerformAdditions)

  • (void)performSelectorInBackground:(SEL)aSelector 


withObject:(id)arg; @end

slide-8
SLIDE 8

Computer Science Science

NSThread *thread = [[NSThread alloc] initWithTarget:someObj selector:@selector(threadMainMethod:)

  • bject:arg];

[thread start]; [NSThread detachNewThreadSelector:@selector(threadMainMethod:) toTarget:someObj withObject:arg]; [someObj performSelectorInBackground:@selector(threadMainMethod:) withObject:arg]

slide-9
SLIDE 9

Computer Science Science

all threads automatically run detached from the creating thread

  • no cleanup is necessary
  • “joining” is not directly supported
  • but this means the thread must have a

means to clean up after itself!

slide-10
SLIDE 10

Computer Science Science

@implementation ViewController

  • (void)viewDidAppear:(BOOL)animated

{ // spawn new thread when view appears [self performSelectorInBackground:@selector(threadMain) withObject:nil]; }

  • (void)threadMain

{ @autoreleasepool { // I need my own autorelease pool! NSLog(@"Hello from thread!"); } }

slide-11
SLIDE 11

Computer Science Science

we often want threads to stick around and process multiple work items — design pattern: thread work queue

slide-12
SLIDE 12

Computer Science Science

workQueue = [[NSMutableArray alloc] init]; [self performSelectorInBackground:@selector(threadMain:) withObject:workQueue]; @synchronized(workQueue) { [workQueue insertObject:@"work item" atIndex:0]; }

  • (void)threadMain:(NSMutableArray *)workQueue

{ @autoreleasepool { id workItem; while (![[NSThread currentThread] isCancelled]) { if (workQueue.count == 0) { [NSThread sleepForTimeInterval:1.0]; continue; } @synchronized(workQueue) { workItem = [workQueue lastObject]; [workQueue removeLastObject]; } // process work item NSLog(@"%@", workItem); } } }

slide-13
SLIDE 13

Computer Science Science

possible extensions:

  • more than one work queue
  • timed (periodic/delayed) work items
  • notifying observers of work completion
  • monitoring of input devices

(asynchronous I/O)

slide-14
SLIDE 14

Computer Science Science

all this and more provided by NSRunLoop — encapsulates multiple input sources & timers, and provides API to dequeue and process work items in the current thread

slide-15
SLIDE 15

Computer Science Science

each work source is associated with one or more run loop modes

  • when executing a run loop, can specify

mode to narrow down work sources

slide-16
SLIDE 16

Computer Science Science

@interface NSRunLoop : NSObject + (NSRunLoop *)currentRunLoop; // enter a permanent run loop, processing items from sources


  • (void)run; 


// process timers and/or one input source before `limitDate'


  • (void)runUntilDate:(NSDate *)limitDate;


 // like runUntilDate, but only for sources in `mode'


  • (BOOL)runMode:(NSString *)mode beforeDate:(NSDate *)limitDate;

@end

slide-17
SLIDE 17

Computer Science Science

  • (void)threadMain {

@autoreleasepool { while (![[NSThread currentThread] isCancelled]) { // process a run loop input source (and/or timers) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; // now do other work before processing run loop sources again NSLog(@"Run loop iteration complete"); } } }

slide-18
SLIDE 18

Computer Science Science

Built in support for delegating work between threads, and for scheduling 
 timed events:

@interface NSObject (NSDelayedPerforming)

  • (void)performSelector:(SEL)aSelector 


withObject:(id)anArgument 
 afterDelay:(NSTimeInterval)delay; @end @interface NSObject (NSThreadPerformAdditions)

  • (void)performSelector:(SEL)aSelector 

  • nThread:(NSThread *)thr 


withObject:(id)arg 
 waitUntilDone:(BOOL)wait;
 @end

slide-19
SLIDE 19

Computer Science Science

  • (void)blinkView {

self.blinkerView.backgroundColor = [UIColor whiteColor]; [UIView animateWithDuration:1.0 animations:^{ self.blinkerView.backgroundColor = [UIColor redColor]; }]; // not a recursive call! [self performSelector:@selector(blinkView) withObject:nil afterDelay:3.0]; }

slide-20
SLIDE 20

Computer Science Science

the main run loop: 
 [NSRunLoop mainRunLoop]

  • this is where everything’s been

happening (until now)!

  • event handling, UI drawing, etc.
slide-21
SLIDE 21

Computer Science Science

event handling can be handed off to other threads, but all UI updates must be performed by the main thread!

slide-22
SLIDE 22

Computer Science Science

dilemma: if UI updates must happen in main thread, how can UI events be processed in secondary threads?

slide-23
SLIDE 23

Computer Science Science

Main Queue execution

Touch Draw Motion Web response needs to perform lengthy processing … but would hold up the main thread if done here

slide-24
SLIDE 24

Computer Science Science

Main Queue execution

Touch Draw Motion Web response

Secondary (background) Queue execution

slide-25
SLIDE 25

Computer Science Science

Main Queue execution

Draw Motion Web response

Secondary (background) Queue execution

Processing Touch

slide-26
SLIDE 26

Computer Science Science

Main Queue execution

Motion Web response

Secondary (background) Queue execution

Processing Draw

slide-27
SLIDE 27

Computer Science Science

Main Queue execution

Web response

Secondary (background) Queue execution

Processing

slide-28
SLIDE 28

Computer Science Science

Main Queue execution

Web response

Secondary (background) Queue execution

Draw Processing

slide-29
SLIDE 29

Computer Science Science

Main Queue execution Secondary (background) Queue execution

Draw

slide-30
SLIDE 30

Computer Science Science

i.e., event processing is outsourced to secondary threads (via run loop); UI updates are performed in the main thread (via main run loop)

slide-31
SLIDE 31

Computer Science Science

@interface NSObject (NSThreadPerformAdditions)

  • (void)performSelectorOnMainThread:(SEL)aSelector 


withObject:(id)arg 
 waitUntilDone:(BOOL)wait; @end @interface NSRunLoop : NSObject + (NSRunLoop *)mainRunLoop; @end interface NSThread : NSObject + (NSThread *)mainThread; @end

Convenience APIs for accessing the main thread / run loop:

slide-32
SLIDE 32

Computer Science Science

  • (IBAction)action:(id)sender forEvent:(UIEvent *)event

{ // outsource event handling to background thread [self performSelector:@selector(processEvent:)

  • nThread:processingThread

withObject:event waitUntilDone:NO]; }

  • (void)processEvent:(UIEvent *)event

{ // process event (in background thread) id result = lengthyProcessing(event); // queue UI update with result in main run loop [self performSelectorOnMainThread:@selector(updateUI:) 
 withObject:result 
 waitUntilDone:NO]; }

  • (void)updateUI:(id)result

{ // update the UI (happens in the main thread) self.label.text = [result description]; }

slide-33
SLIDE 33

Computer Science Science

important: run loops are not thread safe! i.e., don’t access other threads’ run loops directly (use performSelector…)

slide-34
SLIDE 34

Computer Science Science

but manual threading is old school! a host of issues:

  • reusing threads (thread pools)
  • interdependencies & synchronization
  • ideal number of threads?
slide-35
SLIDE 35

Computer Science Science

Grand Central Dispatch is a facility that abstracts away thread-level concurrency with a queue-based API

slide-36
SLIDE 36

Computer Science Science

C API for system-managed concurrency (note: GCD is open sourced by Apple!)

slide-37
SLIDE 37

Computer Science Science

  • 1. Dispatch queues
  • 2. Dispatch sources
slide-38
SLIDE 38

Computer Science Science

void dispatch_async(dispatch_queue_t queue,
 dispatch_block_t block); void dispatch_async_f(dispatch_queue_t queue,
 void *context,
 dispatch_function_t work); void dispatch_sync(dispatch_queue_t queue,
 dispatch_block_t block); void dispatch_sync_f(dispatch_queue_t queue,
 void *context,
 dispatch_function_t work); void dispatch_apply(size_t iterations,
 dispatch_queue_t queue,
 void (^block)(size_t));

slide-39
SLIDE 39

Computer Science Science

// serially process work items for (int i=0; i<N_WORK_ITEMS; i++) { results[i] = process_data(data[i]); } summarize(results, N_WORK_ITEMS); dispatch_queue_t queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0); // process work items in blocks added to queue dispatch_apply(N_WORK_ITEMS, queue, ^(size_t i){ // block code automagically run in threads results[i] = process_data(data[i]); }); summarize(results, N_WORK_ITEMS);

(mini map-reduce)

slide-40
SLIDE 40

Computer Science Science

dispatch queues are backed by threads 
 (# threads determined by system) main & global queues created for every application; can create more if needed

slide-41
SLIDE 41

Computer Science Science

dispatch sources automatically monitor different input sources (e.g., timers, file descriptors, system events) … and schedule blocks on dispatch queues

slide-42
SLIDE 42

Computer Science Science

dispatch_queue_t queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0); dispatch_source_t timer = dispatch_source_create(
 DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0.0); dispatch_source_set_event_handler(timer, ^{ NSLog(@"Beep!"); }); dispatch_resume(timer); 12:28:55.184 QueueTest[72282:1303] Beep! 12:28:56.184 QueueTest[72282:1a03] Beep! 12:28:57.184 QueueTest[72282:1a03] Beep! 12:28:58.184 QueueTest[72282:1a03] Beep! 12:28:59.184 QueueTest[72282:1a03] Beep!

slide-43
SLIDE 43

Computer Science Science

but we rarely use GCD directly

  • low level (ugly) C API
  • source creation is especially irritating
slide-44
SLIDE 44

Computer Science Science

Operation Queue (Cocoa wrapper for GCD)

slide-45
SLIDE 45

Computer Science Science

NSOperationQueue manages operation execution, prioritization, and inter-dependencies

slide-46
SLIDE 46

Computer Science Science

Tasks = NSOperation

slide-47
SLIDE 47

Computer Science Science

concrete subclasses:

  • NSInvocationOperation
  • NSBlockOperation
slide-48
SLIDE 48

Computer Science Science

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue setMaxConcurrentOperationCount:2]; // amount of concurrency 
 NSInvocationOperation *op;


  • p = [[NSInvocationOperation alloc] initWithTarget:self


selector:@selector(taskMethod:)


  • bject:nil];


 NSBlockOperation *bop = [NSBlockOperation blockOperationWithBlock:^{
 // task body
 }]; 
 [bop addExecutionBlock:^{
 // can have multiple concurrent blocks in this operation!
 }]; 
 [bop setCompletionBlock:^{
 // this is run when all execution blocks complete
 }]; 
 [bop addDependency:op]; // bop needs op to complete first (beware cycles!) 
 [queue addOperation:op];
 [queue addOperation:bop]; 
 [queue addOperationWithBlock:^{
 // easier way to schedule a single block as an operation
 }];

slide-49
SLIDE 49

Computer Science Science

but we run into the same issue as before:

  • operation queues are backed by 1+

thread(s), and only the main thread can perform UI updates

  • how to return control to main thread

from operation queues?

slide-50
SLIDE 50

Computer Science Science

as with run loops, currentQueue, mainQueue access specific op-queues — backed by current and main threads

slide-51
SLIDE 51

Computer Science Science

solution:

  • schedule background operations in

secondary queues

  • background operations schedule UI

updates in main queue

slide-52
SLIDE 52

Computer Science Science

  • (IBAction)action:(id)sender forEvent:(UIEvent *)event

[operationQueue addOperationWithBlock:^{ // process event (in background thread) id result = lengthyProcessing(event); [[NSOperationQueue mainQueue] addOperationWithBlock:^{ // update the UI (happens in the main thread) self.label.text = [result description]; }]; }]; }

slide-53
SLIDE 53

Computer Science Science

  • (IBAction)action:(id)sender forEvent:(UIEvent *)event

{ // outsource event handling to background thread [self performSelector:@selector(processEvent:)

  • nThread:processingThread

withObject:event waitUntilDone:NO]; }

  • (void)processEvent:(UIEvent *)event

{ // process event (in background thread) id result = lengthyProcessing(event); // queue UI update with result in main run loop [self performSelectorOnMainThread:@selector(updateUI:) 
 withObject:result 
 waitUntilDone:NO]; }

  • (void)updateUI:(id)result

{ // update the UI (happens in the main thread) self.label.text = [result description]; }

(compare to:)

slide-54
SLIDE 54

Computer Science Science

  • Projects: DominantColors
  • Concurrency with NSOperationQueue
  • Incorporating a C library

Hands-on

slide-55
SLIDE 55

Computer Science Science

§Bonus: Node.js & Event- Driven Programming