[Mac OS development] use gcd to quickly sort the array, and use gcd multithreading to find the maximum value in the array

Function of this example: use gcd to sort an array with 40000 numbers, and the numbers in the array are randomly generated

The generated array code is as follows

    _numsMutableArray = [[NSMutableArray alloc] init];
    
    for (int i = 0; i < 40000; i++) {
        NSNumber *temp = [NSNumber numberWithInt:arc4random_uniform(1000000)];
        [_numsMutableArray addObject:temp];
    }

The generated numbers range from 0 to 1 million, and then they are added to the array.

It is very simple and rough to sort an array with so many numbers in four threads. The idea is to sort different parts of the array in multiple threads first, and then merge. Here, I just arrange it again quickly... Because I can't think of any good merging method. In fact, there is no improvement in the speed of using threads... Just practice how to use objective-c threads first.

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//Create a thread queue
//The following sentence opens up a sub thread
dispatch_async(queue, ^{
    //Call class method quickSort
    [[self class] quickSort:self->_numsMutableArray low:0 high:10000];
});

Open the other three sub threads in the same way.

dispatch_async(queue, ^{
    //Sort the array between 10000 and 20000 bits
    [[self class] quickSort:self->_numsMutableArray low:10001 high:20000];
});
dispatch_async(queue, ^{
    //Sort the array between 20000 and 30000 bits
    [[self class] quickSort:self->_numsMutableArray low:20001 high:30000];
});
dispatch_async(queue, ^{
    //Sort the array between 30000 and 40000 bits
    [[self class] quickSort:self->_numsMutableArray low:30001 high:39999];
});

In this way, the four parts of an array can be ordered, and then the four parts can be sorted again.

[[self class] quickSort:_numsMutableArray low:0 high:39999];

This completes a multi-threaded exercise. gcd is a shallow introduction.

Now we can see whether these threads are parallel or not.

//MARK: gcd
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^{
        //sort
        NSLog(@"10000");
        [[self class] quickSort:self->_numsMutableArray low:0 high:10000];
        NSLog(@"10001");
    });
    dispatch_async(queue, ^{
        //sort
        NSLog(@"20000");
        [[self class] quickSort:self->_numsMutableArray low:10001 high:20000];
        NSLog(@"20001");
    });
    dispatch_async(queue, ^{
        //sort
        NSLog(@"30000");
        [[self class] quickSort:self->_numsMutableArray low:20001 high:30000];
        NSLog(@"30001");
    });
    dispatch_async(queue, ^{
        //sort
        //These log s are in the sub thread. 40000 represents entering the thread and 40001 represents execution completion.
        NSLog(@"40000");
        [[self class] quickSort:self->_numsMutableArray low:30001 high:39999];
        NSLog(@"40001");
    });
//This log is in the main thread
    NSLog(@"jfkdslajflkdsj");

Console output is

2021-05-13 09:33:10.221206+0800 NSOperationPractice[6073:474997] jfkdslajflkdsj
2021-05-13 09:33:10.221214+0800 NSOperationPractice[6073:475037] 10000
2021-05-13 09:33:10.221219+0800 NSOperationPractice[6073:475034] 20000
2021-05-13 09:33:10.221229+0800 NSOperationPractice[6073:475033] 30000
2021-05-13 09:33:10.221250+0800 NSOperationPractice[6073:475036] 40000
2021-05-13 09:33:10.231717+0800 NSOperationPractice[6073:475036] 40001
2021-05-13 09:33:10.232100+0800 NSOperationPractice[6073:475037] 10001
2021-05-13 09:33:10.232303+0800 NSOperationPractice[6073:475033] 30001
2021-05-13 09:33:10.232469+0800 NSOperationPractice[6073:475034] 20001

Run several more times and you will find that the start and end times of these threads are not in the order of 1234. They are executed in parallel. Moreover, although the log in the main thread is written last, it is also output first. If we want to get the maximum value and the minimum value, the idea should be to get the maximum value in four threads, and then compare these four values. How can we get these four values? We cannot directly compare these four threads, because as mentioned above, the main thread executes first. After the four threads are created, let's compare the four sets of code.

Reference link: https://www.jianshu.com/p/5fc974a951fd

When writing four threads before, some people should also think that it is too troublesome to write one by one. Now use the for loop to write.

//Create a thread queue
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.group", DISPATCH_QUEUE_PRIORITY_DEFAULT);
    //Save 4 maximum values with array
    NSMutableArray *tempArray = [[NSMutableArray alloc] init];
    //Create a thread group
    dispatch_group_t group = dispatch_group_create();
    for(int i = 0; i < 4; i++){
        //Create 4 threads in the loop
        dispatch_group_async(group, concurrentQueue, ^{
            //Numsmotablearray is a class method written by myself. It is very simple to find the maximum value. The code is attached at the end.
            int t = [[self class] findTheMaxNumber:self->_numsMutableArray low:i * 10000 high:i * 10000 + 9999];
            [tempArray addObject:@(t)];
//            NSNumber *testNumb = [NSNumber numberWithInt:t]; The @ (t) in the previous sentence is the abbreviation of this sentence, creating an nsnumber object.
        });
    }

    dispatch_group_notify(group, concurrentQueue, ^{
        //The sub thread can enter this code block after execution.
        //NSLog(@"end");
        //NSLog(@"%@",tempArray);
        int finallyMaxNumber = -1;
        for(int i = 0; i < 4; i++){
            if(finallyMaxNumber < [[tempArray objectAtIndex:i] intValue]){
                finallyMaxNumber = [[tempArray objectAtIndex:i] intValue];
            }
        }
        NSLog(@"the max number %d",finallyMaxNumber);
    });

In this way, the maximum value is found.

The code of two class methods is attached below.

In appdelegate H medium

+ (void)quickSort:(NSMutableArray *)array low:(int)low high:(int)high;
+ (int)findTheMaxNumber:(NSMutableArray *)array low:(int)low high:(int)high;

In appdelegate M Medium

+ (int)findTheMaxNumber:(NSMutableArray *)array low:(int)low high:(int)high{
    int maxNumber = -10;
    for(int i = low; i < high; i++){
        if(maxNumber < [array[i] intValue]){
            maxNumber = [array[i] intValue];
        }
    }
    return maxNumber;
}
//Quick sort class method
+ (void)quickSort:(NSMutableArray *)array low:(int)low high:(int)high{
    if(array == nil || array.count == 0){
        return;
    }
    if(low >= high){
        return;
    }
    
    int mid = low + (high - low)/2;
    NSNumber *prmt = array[mid];
    int i = low;
    int j = high;
    
    while(i <= j){
        while([array[i] intValue] < [prmt intValue]){
            i++;
        }
        while([array[j] intValue] > [prmt intValue]){
            j--;
        }
        if(i <= j){
            [array exchangeObjectAtIndex:i withObjectAtIndex:j];
            i++;
            j--;
        }
    }
    if(low < j){
        [[self class]quickSort:array low:low high:j];
    }
    if(high > i){
        [[self class]quickSort:array low:i high:high];
    }
}

Since Objective-C can't guarantee the accuracy of all contents at the beginning of learning, you are welcome to leave a message if there is any error.

Fin.

Keywords: Mac Multithreading objective-c macOS gcd

Added by k.soule on Fri, 11 Feb 2022 17:44:45 +0200