Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

For example, when maintaining a piece of data in memory, multiple places may operate the piece of data at the same time. How can we ensure the security of the piece of data? To do this, the following three conditions need to be met:

  • 1. Read and write are mutually exclusive
  • 2. Write mutually exclusive
  • 3. Read Mutexes
@implementation KCPerson
- (instancetype)init{
    if(self = [super init]){
        _concurrentQueue = dispatch_queue_creat("com.kc_person.syncQueue", DISPATCH_QUEUE_CONCURRENT);
        _dic = [NSMutableDictionary dictionary];
    }
    return self;
}
- (void)kc_setSafeObject:(id)object forKey:(NSString *)key{
    key = [key copy];
    dispatch_barrier_async(_concurrentQueue, ^{
        [_dic setObject:object key:key];
    });
}

- (id)kc_safeObjectForKey:(NSString *)key{
    __block NSString *temp;
    dispatch_sync(_concurrentQueue, ^{
        temp = [_dic objcetForKey:key];
    });
    return temp;
}
@end
Copy the code
  • First we need to maintain a GCD queue, preferably not global queue, after all, we all know that global queue encounter fence function is pit point, here will not analyze! There is no judgment or processing of the fence function in the global queue. Therefore, the fence function in the global queue is no different from the normal synchronous or asynchronous function.

  • Because the considerations of performance, deadlock, and congestion do not consider the traversal queue, use custom concurrent queue! _concurrentQueue = dispatch_queue_creat(“com.kc_person.syncQueue”, DISPATCH_QUEUE_CONCURRENT);

  • First let’s look at the read operation: kc_safeObjectForKey we can’t use asynchronous function because of multithreading! Description:

    • Thread 2 gets:nameThread 3 fetchage
    • If there is confusion due to asynchronous concurrency, the original read isname“, the result readage
    • We allow multiple tasks in at the same time! But the read operation needs to return synchronously, so we choose:Synchronization function(Read and write)
  • Let’s take a look at the write operation. The key is copied during the write operation. Insert a quote from the reference to explain this:

The function caller is free to pass an NSMutableString key and can modify it after the function returns. So we must copy the string we pass in to make sure the function works. If the string passed in is not mutable (that is, the normal NSString type), calling copy is essentially a null operation.

  • So here we choosedispatch_barrier_asyncWhy is the fence function instead of asynchronous function or synchronous function?
    • Fence function task: all previous tasks are completed, and no other tasks are executed until the task after it starts, so it is better to encourage write operation after write (write mutually exclusive), no mess!
    • Why not an asynchronous function? Asynchronous functions can be confusing
    • Why not use a synchronization function? If both the read and write operations are performed, then with the synchronization function, there is a possibility that I need to wait for the read operation to come back, obviously not reasonable!