Talking about several kinds of lock _ios in IOS

Source: Internet
Author: User
Tags exception handling gcd mutex semaphore

1 Preface

Recent work is not too busy, just have time to understand some other things, originally intended to go to the physical examination this morning, but to see the weather or tomorrow to go again, there is a big reason: there is no appointment in Saturday! Less gossip, here simple to lock a simple introduction to share.

2 Directory

    1. The first part: what is a lock
    2. Part II: Classification of Locks
    3. Part III: The role of the lock
    4. Part IV: Implementation of the lock in iOS

The first part: what is a lock

From an early age to know the lock, is the home door of the lock, used to prevent theft of the lock. It also has a key for unlocking. But the lock here is not a childhood cognitive lock, but a lock at the programmer's point of view. Here I will introduce the lock according to my understanding.

In computer science, locks are a synchronization mechanism for enforcing access restrictions on resources in environments where there are multiple threads. You can understand it as a strategy for excluding concurrency. See examples

if (lock = = 0) {
lock = mypid;
}

The above code does not guarantee that the task has a lock, so it can be executed by multiple tasks at the same time. At this point it is possible that multiple tasks have detected that lock is idle, so two or more tasks will attempt to set lock, without knowing that other tasks are attempting to set lock. This time there will be a problem.
And take a look at this piece of code:

Class Acccount {
long val = 0;//This cannot be modified in any other way and can only be modified by Add/minus
Object thislock = new Object ();
public void Add (const long x) {
lock (thislock) {
  val +=x;
}
}
public void minus (const long x) {
lock (thislock) {
  val-=x;
  }
}
}

This prevents multiple tasks from modifying Val (note that if Val is public, that can also cause problems).

Part II: Classification of Locks

Locks can be grouped into different classes depending on their nature.

In the Wikipedia introduction, the general lock is the recommended lock, and for each of the four tasks to access the public resources, you need to obtain information about the lock, and then based on the lock information to determine whether access. If access to the corresponding information, the lock state will change to lock, so other threads do not access the resource, when the end of access, the lock will be released, allowing other tasks to access. Some systems have forced locks, and if unauthorized locks access locked data, an exception is generated when accessing it.
In iOS, locks are divided into recursive locks, conditional locks, distributed locks, and general locks (this is seen in the Nslock category).
For the lock classification of the database:

Classification Method Classification
According to the size of the lock division Table-level locks, row-level locks, page-level locks
Divide by level of locks Shared locks, exclusive locks
Divide by the way of lock Automatic lock, display lock
By the way the locks are used Optimistic lock, pessimistic lock
Divide by operation DML locks, DDL locks

This is not a detailed introduction, interested members can check the relevant information themselves.

Part III: The role of the lock

This is more popular: in order to prevent the multithreading (multitasking) in the case of shared resources (critical resources) dirty read or dirty write. It can also be understood as the synchronization mechanism used to enforce restrictions on resource access when executing multiple threads, that is, the requirement to guarantee mutual exclusion in concurrent control.

Part IV: Implementation of the lock in iOS

First look at the. h file in iOS Nslock class. It's not written here. As you can see from the code, the class is divided into subclasses: Nslock, Nsconditionlock, Nsrecursivelock, and Nscondition. And then there's a nslocking agreement:

@protocol nslocking
-(void) lock;
-(void) unlock;
@end

These subclasses follow the Nslock protocol, and here are a few of the ways to do this:

For the Trylock method, try to get a lock and immediately return the bool value, yes to acquire the lock, and no to indicate that the lock failed to be acquired. Lockbeforedate: Method to acquire a lock before a certain time, and if successful, return Yes,no to indicate the acquisition lock failed. Next let's look at how the lock is implemented in iOS:

Mode 1 using the Nslock class

-(void) Nslockdemo {
  Nslock *mylock = [[Nslock alloc] init];
  _testlock = [[Testlock alloc] init];
  Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{
    [MyLock lock];
    [_testlock method1];
    Sleep (5);
    [MyLock unlock];
    if ([MyLock Trylock]) {
      NSLog (@ "can get Lock");
    } else {
      NSLog (@ "Can not get");
    }
  )
  ; Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{sleep
    (1);
    if ([MyLock Trylock]) {
      NSLog (@ "---can get a lock");
    } else {
      NSLog (@ "----can not get the");
    }
    [MyLock lock];
    [_testlock METHOD2];
    [MyLock unlock];}

Mode 2 using @synchorize

-(void) Synchronizedemo {
  _testlock = [[Testlock alloc] init];
  Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{
    @synchronized (_testlock) {
      [_testlock method1];
      Sleep (5);
    }
  });
  Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{sleep
    (1);
    @synchronized (_testlock) {
      
      [_testlock method2];}}
  );

For the testlock used in the synchorize instruction, the lock is only satisfied when the mark is the same. The advantage of this is that you can implement the lock mechanism without explicitly creating a lock. But it implicitly adds an exception handler to protect the code, which automatically releases the lock when it throws an exception.

Mode 3 using GCD

-(void) Gcddemo {
  _testlock = [[Testlock alloc] init];
  dispatch_semaphore_t semaphore = dispatch_semaphore_create (1);
  Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{
    dispatch_semaphore_wait ( semaphore, dispatch_time_forever);
    [_testlock method1];
    Sleep (5);
    Dispatch_semaphore_signal (semaphore);
  });
  Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{sleep
    (1);
    Dispatch_semaphore_wait (semaphore, dispatch_time_forever);
    [_testlock METHOD2];
    Dispatch_semaphore_signal (semaphore);}



Mode 4 using Phtread

-(void) Pthreaddemo {
  _testlock = [[Testlock alloc] init];
  
  __block pthread_mutex_t Mutex;
  Pthread_mutex_init (&mutex, NULL);
  
  Thread 1
  dispatch_async (dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{
    pthread_mutex_ Lock (&mutex);
    [_testlock method1];
    Sleep (5);
    Pthread_mutex_unlock (&mutex);
  });
  
  Thread 2
  dispatch_async (dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{sleep
    (1);
    Pthread_mutex_lock (&mutex);
    [_testlock METHOD2];
    Pthread_mutex_unlock (&mutex);}

pthread_mutex_t defined in Pthread.h, so remember #include.

3 Performance Comparison

Here simply write a small program to perform the performance comparison of the four ways, there is a fixed number of times in the lock unlocked, and then output, the results are as follows (test 1, 2 execution times are not the same: Test 1 < test 2):

Test 1

2016-11-05 15:27:52.595 lockdemo[4394:202297] Nslock times:0.871843
2016-11-05 15:27:56.335 lockdemo[4394:202297] synthorize times:3.738939
2016-11-05 15:27:56.691 lockdemo[4394:202297] GCD times:0.355344
2016-11-05 15:27:57.328 lockdemo[4394:202297] pthread times:0.636815
2016-11-05 15:27:57.559 lockdemo[4394:202297] Osspinlock times:0.231013
2016-11-05 15:27:57.910 lockdemo[4394:202297] Os_unfair_lock times:0.350615

Test 2

2016-11-05 15:30:54.123 lockdemo[4454:205180] Nslock times:1.908103
2016-11-05 15:31:02.112 lockdemo[4454:205180] synthorize times:7.988547
2016-11-05 15:31:02.905 lockdemo[4454:205180] GCD times:0.792113
2016-11-05 15:31:04.372 lockdemo[4454:205180] pthread times:1.466987
2016-11-05 15:31:04.870 lockdemo[4454:205180] Osspinlock times:0.497487
2016-11-05 15:31:05.637 lockdemo[4454:205180] Os_unfair_lock times:0.767569

The Osspinlock is also tested (this class has been replaced by Os_unfair_lock). The results are as follows:

Synthorize > Nslock > Pthread > GCD > Os_unfair_lock >osspinlock

Over here:

Exception handling is added inside the synthorize, so it is time-consuming.

Pthread_mutex the underlying API, the processing power is good.

GCD System Package C code effect is better than pthread.

4 Summary

Simple to introduce so much.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.