Pthread_cleanup_push ()/pthread_cleanup_pop ()

Source: Internet
Author: User

Generally, there are two scenarios for POSIX thread termination: normal termination and abnormal termination. When the thread actively calls pthread_exit () or returns from the thread function, the thread Exits normally. This is a foreseeable exit method. Abnormal Termination is performed by the thread under the intervention of other threads, or exit because of an error in your own operation (for example, access to an Invalid Address). This exit method is unpredictable.

Whether it is foreseeable thread termination or abnormal termination, there will be a problem of resource release, without considering the exit due to a running error, how to ensure that the resources occupied by the thread can be released smoothly when the thread is terminated, especially the resource lock, is a problem that must be considered.

The most common situation is the use of the resource exclusive lock: the thread adds a lock to the critical resource for access, but is canceled by the outside during the access process. If the thread is in the canceled response state, in addition, when an asynchronous response is used, or a cancellation point exists in the running path before the exclusive lock is opened, the critical resource will always be locked and cannot be released. Undo operations are unpredictable, so a mechanism is required to simplify the programming for resource release.

In the POSIX thread API, A pthread_cleanup_push ()/pthread_cleanup_pop () function is provided between the call point of pthread_cleanup_push () and pthread_cleanup_pop ().ProgramThe termination action (including calling pthread_exit () and canceling point termination) in the section will execute the cleanup function specified by pthread_cleanup_push. The API is defined as follows:

Void pthread_cleanup_push (void (* routine) (void *), void * Arg)
Void pthread_cleanup_pop (INT execute)

Pthread_cleanup_push ()/pthread_cleanup_pop () adopts the stack structure management that comes first and then goes out. The Void routine (void * Arg) function is pushed into the cleanup function stack when pthread_cleanup_push () is called, multiple calls to pthread_cleanup_push () form a function chain in the clear function stack. When executing the function chain, it pops up in the reverse order of the Pressure stack. The execute parameter indicates whether to execute the cleanup function while pthread_cleanup_pop () is displayed. If it is set to 0, it indicates that the function is not executed. If it is not set to 0, it indicates that the function is executed; this parameter does not affect the execution of the cleanup function when an exception is terminated.

Pthread_cleanup_push ()/pthread_cleanup_pop () is implemented in macro format, which is the macro definition in pthread. h:

 # Define pthread_cleanup_push (routine, ARG) 
{Struct _ pthread_cleanup_buffer _ buffer;
_ Pthread_cleanup_push (& _ buffer, (routine), (ARG ));
# Define pthread_cleanup_pop (execute)
_ Pthread_cleanup_pop (& _ buffer, (execute ));}
It can be seen that pthread_cleanup_push () carries a "{", while pthread_cleanup_pop () carries a "}". Therefore, these two functions must appear in pairs and must be at the same level of the programCodeCan be compiled. In the following example, when the thread stops in "Do some work", pthread_mutex_unlock (MUT) will be called to complete the unlock action.
When the work is terminated, pthread_mutex_unlock (MUT) is called to complete the unlock action.
Pthread_cleanup_push (pthread_mutex_unlock, (void *) & MUT );
Pthread_mutex_lock (& MUT );
/* Do some work */
Pthread_mutex_unlock (& MUT );
Pthread_cleanup_pop (0 );
It must be noted that if the thread is in the pthread_cancel_asynchronous state, the above Code segment may fail because the cancel event may
Pthread_cleanup_push () and pthread_mutex_lock () occur, or between pthread_mutex_unlock () and pthread_cleanup_pop (), which causes the unlock function to be unlocked.
Mutex variable, causing an error. Therefore, when using the cleanup function, you should temporarily set it to the pthread_cancel_deferred mode. Therefore, POSIX
In Linux, a pair of pthread_cleanup_push_defer_np ()/pthread_cleanup_pop_defer_np () Extension functions are also provided.
Code segment equivalent:
{Int oldtype;
Pthread_setcanceltype (pthread_cancel_deferred, & oldtype );
Pthread_cleanup_push (routine, ARG );
...
Pthread_cleanup_pop (execute );
Pthread_setcanceltype (oldtype, null );
}
 
The parts marked with red above are the key functions of these two functions. My understanding is:
Pthread_cleanup_push (pthread_mutex_unlock, (void *) & MUT );
Pthread_mutex_lock (& MUT );
/* Do some work */
Pthread_mutex_unlock (& MUT );
Pthread_cleanup_pop (0 );
After do some work, pthread_mutex_unlock (& MUT) exists, that is, there is an unlock operation.But do some work may end abnormally. In that case, the system willThe functions provided in pthread_cleanup_push can be used to unlock parameters or perform other operations to avoid deadlock!

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.