Locks in objective-C

Source: Internet
Author: User
The lock is the basis of the thread programming synchronization tool. The lock makes it easy to protect a large part of the code so that you can ensure the correctness of the Code. 1 use POSIX mutex   POSIX mutex lock is easy to use in many programs. To create a mutex lock, you declare and initialize a pthread_mutex_t structure. To lock and unlock a mutex, you can use the pthread_mutex_lock and pthread_mutex_unlock functions. List 4-2 lists the basic code for initializing and using a POSIX thread mutex lock. After a lock is used up, you only need to call pthread_mutex_destroy to release the data structure of the lock.     Listing 4-2     Using a mutex lock pthread_mutex_t mutex;     Void myinitfunction ()     {         Pthread_mutex_init (& mutex, null );     }     Void mylockingfunction ()     {         Pthread_mutex_lock (& mutex );         // Do work. pthread_mutex_unlock (& mutex );     }   Note: The above code is just a simple explicit step to use a POSIX thread mutex lock. Your own code should check the error codes returned by these functions and handle them as appropriate. 4.6.2 use nslock class   In the cocoa program, nslock implements a simple mutex lock. All the locks (including nslock) interfaces are actually defined through the nslocking Protocol, which defines the lock and Unlock methods. You can use these methods to obtain and release the lock.   In addition to the standard lock behavior, the nslock class also adds the trylock and lockbeforedate: methods. Method trylock tries to get a lock, but if the lock is unavailable, it will not block the thread. Instead, it only returns no. Lockbeforedate: The method tries to obtain a lock, but if the lock is not obtained within the specified time, it will change the thread from blocking to non-blocking (or return no ).   In the following example, you can use an nslock object to update a visualization explicit object. Its data structure is calculated by multiple threads. If the thread does not get the lock immediately, it simply continues to calculate until it can get the lock and then update the explicit expression.     Bool moretodo = yes;     Nslock * thelock = [[nslock alloc] init];     ...     While (moretodo ){                             If ([thelock trylock]) {                           [Thelock
Unlock];         }     } 4.6.3 use the @ synchronized command   @ Synchronized is a convenient method to create a mutex lock in the objective-C code. @ Synchronized Command performs the same work as other mutex locks (it prevents different threads from obtaining the same lock at the same time ). However, in this case, you do not need to directly create a mutex lock or lock object. Instead, you only need to simply use the objective-C object as the lock token, as shown in the following example:     -(Void) mymethod :( ID) anobj     {         @ Synchronized (anobj)         {             //
Everything between the braces is protected by the @ synchronized directive.         }     }   The object created for @ synchronized is a unique identifier used to differentiate protection blocks. If you execute the above method in two different threads and each time a different object is passed to the anobj parameter in a thread, each time it will have its lock and it will be continuously processed, it is not blocked by other threads. However, if you pass the same object, one thread in multiple threads will first obtain the lock, and other threads will be blocked until the first thread completes its critical section.   As a precaution, @ synchronized implicitly adds an exception handling routine to protect the code. This processing routine Automatically releases the mutex when an exception is thrown. This means that to use the @ synchronized command, you must enable Exception Handling in your code. If you don't want the implicit exception handling routine to bring additional overhead, you should consider using the lock class. 4.6.4 use other cocoa locks   The following section describes how to use other types of cocoa locks. · Use nsrecursivelock object   The lock defined by the nsrecursivelock class can be obtained multiple times in the same thread without causing a deadlock. A recursive lock will track how many times it is successfully obtained. Each successful acquisition of the lock must balance the call locks and unlock operations. Only when all lock and unlock operations are balanced can the lock be truly released to other threads.   As its name says, this type of lock is usually used in a recursive function to prevent recursion from causing blocking threads. You can use it to call functions in a non-recursive manner. The Semantics of these functions requires that they use locks. The following is a simple recursive function that acquires locks in recursion. If you do not use the nsrecursivelock object in this Code, the thread will experience a deadlock when the function is called again.    
Nsrecursivelock * thelock = [[nsrecursivelock alloc] init];     Void myrecursivefunction (INT value ){         [Thelock lock];         If (value! = 0 ){             -- Value;             Myrecursivefunction (value );         }       [Thelock unlock];     }     Myrecursivefunction (5 );   Note: because a recursive lock will not be released until the call of all locks uses the unlock operation in balance, you must carefully weigh whether to determine the potential impact of using the lock on performance. Holding a lock for a long time will cause other threads to block until recursion is completed. If you can rewrite your code to eliminate recursion or eliminate the use of a recursive lock, you may get better performance. · Use nsconditionlock object   The nsconditionlock object defines a mutex lock, which can be locked and unlocked with specific values. Do not confuse the locks and conditions of this type (see the "condition" section. Its behavior and conditions are similar, but their implementation is very different.   Generally, when multiple threads need to execute tasks in a specific order, you can use an nsconditionlock object. For example, when one thread produces data and the other thread consumes data. When the producer executes the lock, the consumer uses the condition specified by your program to obtain the lock (the condition itself is an integer value you define ). When the producer completes, it will unlock the lock and set the lock condition to an appropriate integer value to wake up the consumer thread, and then the consumer thread continues to process data.   The nsconditionlock lock and Unlock methods can be used in any combination. For example, you can use unlockwithcondition: And lock messages, or use lockwhencondition: And unlock messages. Of course, the subsequent combinations can unlock a lock but may not release any threads waiting for a specific condition value.   The following example shows how to use conditional locks to handle producer-consumer issues. Imagine an application containing a data queue. A producer thread adds data to the queue, while the consumer thread extracts data from the queue. The producer does not need to wait for specific conditions, but it must wait for the lock to be available so that it can safely add data to the queue.     Id condlock = [[nsconditionlock alloc] initwithcondition: no_data];     While (true ){         [Condlock lock];                 [Condlock unlockwithcondition: has_data];     }   Because the value of the initialization condition lock is no_data, the producer thread can obtain the lock without any problem during initialization. It adds queue data and sets the condition as has_data. In subsequent iterations, the producer thread can add the data to the queue, regardless of whether the queue is empty or there is still data. The only way to block it is when a consumer thread fills the queue to retrieve data.   Because the consumer thread must have data to process, it will use a specific condition to wait for the queue. When the producer puts data into the queue, the consumer thread is awakened and the lock is obtained. It can retrieve data from the queue and update the status of the queue. The following code shows the basic structure of the consumer thread processing loop.     While (true ){         [Condlock lockwhencondition: has_data];                   [Condlock unlockwithcondition :( isempty? No_data: has_data)];         // Process the data locally.     }. Use nsdistributedlock object   The nsdistributedlock class can be used by multiple applications on multiple hosts to restrict access to some shared resources, such as a file. The lock itself is an efficient mutex lock, which is implemented by a file system project, such as a file or directory. For an available nsdistributedlock object, the lock must be written by all programs that use it. This usually means that it is stored in a file system which can be accessed by all applications running on a computer.   Unlike other types of locks, nsdistributedlock does not implement the nslocking protocol, and it does not have the lock method. A lock method will block thread execution and require the system to poll the lock at a predetermined speed. With this constraint in your code, nsdistributedlock provides a trylock method and lets you decide whether to poll.   Because it is implemented by the file system, an nsdistributedlock object will not be released unless its owner explicitly releases it. If your program crashes when the user has a Distributed Lock, other clients cannot access the protected resource. In this case, you can use the breadlock method to break the existing lock so that you can obtain it. However, you should avoid breaking the lock unless you are sure that the lock is no longer likely to be released after the process has been killed.

 

Like other types of locks, when you use an nsdistributedlock object, you can call the unlock method to release it.

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.