Search code examples
objective-cconcurrencygrand-central-dispatchnsoperation

How to Print Natural Numbers Sequentially but in 2 different threads Objective-C


I'm new to working with concurrency in Objective-C. I've taken look at some demo codes of concurrency programming.

I want to print natural numbers sequentially but in 2 different threads. Like:

1: Thread-XX

2: Thread-YY

3: Thread-XX

4: Thread-YY

5: Thread-XX

6: Thread-YY

.....................

.....................

and so on. But I can't figure out how to do that. Any help?


Solution

  • We can show you how to do this, but it's not a very useful scenario. You're going to spent a lot of time coordinating these two threads with semaphores or the like, largely diminishing the value of having stuff running on multiple threads. Often when you write multithreaded code, you want to maximize concurrency by minimizing the amount of time spent waiting for some signal from some other thread. This attempt to alternate between these two threads is antithetical to our general intent of multithreaded programming.

    That having been said, it could look a bit like:

    dispatch_queue_t xx = dispatch_queue_create("xx", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t yy = dispatch_queue_create("yy", DISPATCH_QUEUE_SERIAL);
    
    dispatch_semaphore_t semaphoreXX = dispatch_semaphore_create(0);
    dispatch_semaphore_t semaphoreYY = dispatch_semaphore_create(1);     // seed this with one extra signal from YY
    
    NSInteger __block value = 0;
    
    dispatch_async(xx, ^{
        for (NSInteger i = 0; i < 100; i++) {
            dispatch_semaphore_wait(semaphoreYY, DISPATCH_TIME_FOREVER); // wait for signal from YY
            value += 1;
            NSLog(@"%ld: xx", (long)value);
            [NSThread sleepForTimeInterval:0.1];                         // 1/10 second delay so we can see what's going on
            dispatch_semaphore_signal(semaphoreXX);                      // send signal from XX
        }
    });
    
    dispatch_async(yy, ^{
        for (NSInteger i = 0; i < 100; i++) {
            dispatch_semaphore_wait(semaphoreXX, DISPATCH_TIME_FOREVER); // wait for signal from XX
            value += 1;
            NSLog(@"%ld: yy", (long)value);
            [NSThread sleepForTimeInterval:0.5];                         // 1/2 second delay so we can see what's going on
            dispatch_semaphore_signal(semaphoreYY);                      // send signal from YY
        }
    });
    

    Usually when we're updating one variable from multiple threads, we'd synchronize our access to that object, but this "have the threads alternate" logic eliminates our need to do that, in this particular case.