cs24-22fa pthread_mutex_lock

Introduction to Computing Systems (Fall 2022)

Name

pthread_mutex_lock, pthread_mutex_unlock — lock and unlock a mutex

Synopsis

#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

Description

The mutex object referenced by mutex shall be locked by a call to pthread_mutex_lock() that returns zero or [EOWNERDEAD]. If the mutex is already locked by another thread, the calling thread shall block until the mutex becomes available. This operation shall return with the mutex object referenced by mutex in the locked state with the calling thread as its owner. If a thread attempts to relock a mutex that it has already locked, pthread_mutex_lock() shall behave as described in the Relock column of the following table. If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, pthread_mutex_unlock() shall behave as described in the Unlock When Not Owner column of the following table.

Mutex Type Robustness Relock Unlock When Not Owner
Normal Non-Robust Deadlock Undefined Behavior
Normal Robust Deadlock Error Returned
Error Check Either Error Returned Error Returned
Recursive Either Recursive Error Returned
Default Non-Robust Undefined Behavior Undefined Behavior
Default Robust Undefined Behavior Error Returned

By default (attr == NULL), mutexes are non-robust (PTHREAD_MUTEX_STALLED).

The pthread_mutex_unlock() function shall release the mutex object referenced by mutex. The manner in which a mutex is released is dependent upon the mutex’s type attribute. If there are threads blocked on the mutex object referenced by mutex when pthread_mutex_unlock() is called, resulting in the mutex becoming available, the scheduling policy shall determine which thread shall acquire the mutex.

If mutex does not refer to an initialized mutex object, the behavior of pthread_mutex_lock(), and pthread_mutex_unlock() is undefined.

Example

#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

const size_t TOTAL = 1000;
uint64_t count;
pthread_mutex_t mutex;

void *child(void *arg) {
    uint64_t temp = 0;

    for (size_t i = 0; i < TOTAL; i++) {
        temp += i;
    }

    pthread_mutex_lock(&mutex);
    count += temp;
    pthread_mutex_unlock(&mutex);

    return NULL;
}

int main(int argc, char *argv[]) {
    pthread_mutex_init(&mutex, NULL);

    pthread_t p[10];
    for (size_t i = 0; i < 10; i++) {
        pthread_create(&p[i], NULL, child, NULL);
    }

    for (size_t i = 0; i < 10; i++) {
        pthread_join(p[i], NULL);
    }

    printf("Final result: %llu\n", count);

    pthread_mutex_destroy(&mutex);
    return 0;
}

Return Value

If successful, the pthread_mutex_lock(), and pthread_mutex_unlock() functions shall return zero; otherwise, an error number shall be returned to indicate the error.

See Also

pthread_mutex_init(), pthread_mutex_destroy(), pthread_cond_wait()