Embedded Linux: Registering Thread Cleanup Handlers

Embedded Linux: Registering Thread Cleanup Handlers

Click the blue text above to follow us

In Linux multithreading programming, specific cleanup operations can be performed when a thread terminates by registering a thread cleanup handler.

Embedded Linux: Registering Thread Cleanup Handlers

This is similar to using atexit() to register process termination handlers.

The thread cleanup handler is used to perform resource release or cleanup tasks when a thread exits, such as closing file descriptors, releasing memory, etc.

Unlike processes, threads can register multiple cleanup handlers, which are managed in a stack structure—a last-in-first-out data structure.

Therefore, the execution order of cleanup handlers is the reverse of the registration order.

In Linux, the pthread_cleanup_push() and pthread_cleanup_pop() functions are used to add and remove cleanup handlers from the thread’s cleanup handler stack.

The prototypes are as follows:

void pthread_cleanup_push(void (*routine)(void *), void *arg);void pthread_cleanup_pop(int execute);

Parameter descriptions:

  • pthread_cleanup_push(): Used to push a cleanup handler onto the stack.

    • routine: A function pointer to the cleanup handler, which has no return value and accepts a void * parameter.

    • arg: The argument passed to the cleanup handler, which serves as input to routine() when the cleanup handler is executed.

  • pthread_cleanup_pop(): Used to pop the most recently added cleanup handler from the cleanup handler stack.

    • execute: Specifies whether to execute the cleanup handler. If it is 0, only the cleanup handler is removed without execution; if non-zero, the cleanup handler is removed and executed.

Scenarios for executing thread cleanup handlers:

  • When a thread calls pthread_exit() to exit, the cleanup handlers are executed automatically.

  • When a thread responds to a cancel request (e.g., by canceling the thread with pthread_cancel()), the cleanup handlers are executed.

  • When pthread_cleanup_pop() is called with a non-zero argument, the top cleanup handler on the stack is executed.

The following code demonstrates how to register and remove cleanup handlers using pthread_cleanup_push() and pthread_cleanup_pop():

void cleanup(void *arg) {    printf("Cleaning up: %s\n", (char *)arg);}
void *thread_function(void *arg) {    pthread_cleanup_push(cleanup, "Resource 1");    pthread_cleanup_push(cleanup, "Resource 2");
    // Simulate thread work    printf("Thread is running...\n");
    // Calling pthread_exit() will trigger cleanup handler execution    pthread_exit(NULL);
    // Cleanup handlers must be used in pairs, so even after exit, pthread_cleanup_pop must be called    pthread_cleanup_pop(1);    pthread_cleanup_pop(1);}
int main() {    pthread_t thread;
    // Create a thread    if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {        perror("Failed to create thread");        return 1;    }
    // Wait for the thread to finish    pthread_join(thread, NULL);    return 0;}

Explanation:

  • Two cleanup handlers are registered in the thread, namely “Resource 1” and “Resource 2”.

  • When the thread calls pthread_exit(), the cleanup handlers in the stack are executed in last-in-first-out order, so it will first print “Cleaning up: Resource 2”, then print “Cleaning up: Resource 1”.

Notes:

  • pthread_cleanup_push() and pthread_cleanup_pop() are not ordinary functions but are implemented as macros, and must appear in pairs within the same scope. They cannot be used separately in the code.

  • Cleanup handlers will only be executed when the thread exits via pthread_exit() or responds to a cancel request.

    If a thread exits via a return statement, the cleanup handlers will not be executed.

By using pthread_cleanup_push() and pthread_cleanup_pop(), you can ensure that the necessary cleanup operations are executed when a thread terminates, which is very useful in resource management and exception handling.

The automatic execution of cleanup handlers makes resource release in multithreading programming more concise and secure.

Embedded Linux: Registering Thread Cleanup Handlers
Embedded Linux: Registering Thread Cleanup Handlers
Click Read the Original for more exciting content~

Leave a Comment