### 详细描述

Cobalt/POSIX 互斥服务。

互斥锁是一种 MUTual EXclusion 设备，用于保护共享数据结构免受并发修改，并实现临界区和监视器。

互斥锁有两种可能的状态：未锁定（未被任何线程拥有）和锁定（被一个线程拥有）。互斥锁永远不能同时被两个不同的线程拥有。尝试锁定已被其他线程锁定的互斥锁的线程将被挂起，直到拥有线程首先解锁该互斥锁。

在使用之前，必须使用 `pthread_mutex_init()` 初始化互斥锁。可以传递给该服务的属性对象允许选择创建的互斥锁的特性，即其类型（参见 `pthread_mutexattr_settype()`）、使用的优先级协议（参见 `pthread_mutexattr_setprotocol()`）以及是否可以在多个进程之间共享（参见 `pthread_mutexattr_setpshared()`）。

默认情况下，Cobalt 互斥锁是普通类型，不使用优先级协议，并且不能在多个进程之间共享。

请注意，应使用 `pthread_mutex_init()` 初始化互斥锁，使用静态初始化器 `PTHREAD_MUTEX_INITIALIZER` 将延迟初始化到第一次调用互斥锁的方法，并且很可能引入切换到次级模式。互斥锁服务的文档（特别是 API 标签）假设互斥锁已通过 `pthread_mutex_init()` 显式初始化。

---
### 函数文档

#### \_\_attribute\_\_()

> static int \_\_attribute\_\_((cold))

测试互斥锁结构是否包含有效的自动初始化器。

**返回值:**
- 成功时返回互斥锁类型；
- 如果不在支持的自动初始化器状态，则返回 `-1`。

#### __pthread_mutex_lock()

> static int __pthread_mutex_lock (pthread_mutex_t * mutex)

**锁定互斥锁。**

该服务尝试锁定互斥锁 `mx`。如果互斥锁是空闲的，它将被锁定。如果它已被当前线程以外的其他线程锁定，当前线程将被挂起，直到互斥锁被解锁。如果它已被当前线程锁定，该服务的行为取决于互斥锁的类型：

- 对于 `PTHREAD_MUTEX_NORMAL` 类型的互斥锁，该服务会导致死锁；
- 对于 `PTHREAD_MUTEX_ERRORCHECK` 类型的互斥锁，该服务返回 `EDEADLK` 错误号；
- 对于 `PTHREAD_MUTEX_RECURSIVE` 类型的互斥锁，该服务递增锁递归计数并返回 0。

**参数:**
- `mutex` - 要锁定的互斥锁。

**返回值:**
- 成功时返回 `0`。
- 如果出错，返回错误号：
    - `EPERM`，调用者无权执行该操作；
    - `EINVAL`，互斥锁 `mx` 无效；
    - `EPERM`，互斥锁不是进程共享的，并且不属于当前进程；
    - `EDEADLK`，互斥锁是 `PTHREAD_MUTEX_ERRORCHECK` 类型，并且已被当前线程锁定；
    - `EAGAIN`，互斥锁是 `PTHREAD_MUTEX_RECURSIVE` 类型，并且已超过最大递归锁定次数。

**标签:** `xthread-only`，`switch-primary`

#### __pthread_mutex_timedlock()

> static int __pthread_mutex_timedlock (pthread_mutex_t * mutex, const struct timespec * to)

**在限定时间内尝试锁定互斥锁。**

该服务等效于 `pthread_mutex_lock()`，但如果互斥锁 `mx` 被当前线程以外的其他线程锁定，该服务仅挂起当前线程，直到 `to` 指定的超时时间到期。

**参数:**
- `mutex` - 要锁定的互斥锁；
- `to` - 超时时间，以 `CLOCK_REALTIME` 时钟的绝对值表示。

**返回值:**
- 成功时返回 `0`。
- 出错时返回错误号：
    - `EPERM`，调用者无权执行该操作；
    - `EINVAL`，互斥锁 `mx` 无效；
    - `EPERM`，互斥锁不是进程共享的，并且不属于当前进程；
    - `ETIMEDOUT`，互斥锁无法锁定且指定的超时时间已到；
    - `EDEADLK`，互斥锁是 `PTHREAD_MUTEX_ERRORCHECK` 类型，并且已被当前线程锁定；
    - `EAGAIN`，互斥锁是 `PTHREAD_MUTEX_RECURSIVE` 类型，并且已超过最大递归锁定次数。

**标签:** `xthread-only`，`switch-primary`

#### pthread_mutex_destroy()

> int pthread_mutex_destroy (pthread_mutex_t * mutex)

**销毁互斥锁。**

该服务销毁互斥锁 `mutex`，前提是它未被锁定且未被任何条件变量引用。销毁后，互斥锁对于所有互斥锁服务（除了 `pthread_mutex_init()`）都变为无效（它们都会返回 `EINVAL` 错误）。

**参数:**
- `mutex` - 要销毁的互斥锁。

**返回值:**
- 成功时返回 `0`。
- 出错时返回错误号：
    - `EINVAL`，互斥锁 `mutex` 无效；
    - `EPERM`，互斥锁不是进程共享的，并且不属于当前进程；
    - `EBUSY`，互斥锁已被锁定或被条件变量使用。

**标签:** `thread-unrestricted`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 5

pthread_mutex_t mutex;
int shared_counter = 0;

void* increment_counter(void* arg) {
    for (int i = 0; i < 100000; i++) {
        pthread_mutex_lock(&mutex);
        shared_counter++;  // 访问共享资源
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];

    // 初始化互斥锁
    if (pthread_mutex_init(&mutex, NULL) != 0) {
        perror("Mutex initialization failed");
        return EXIT_FAILURE;
    }

    // 创建多个线程
    for (int i = 0; i < NUM_THREADS; i++) {
        if (pthread_create(&threads[i], NULL, increment_counter, NULL) != 0) {
            perror("Thread creation failed");
            return EXIT_FAILURE;
        }
    }

    // 等待所有线程完成
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }

    printf("Final counter value: %d\n", shared_counter);

    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return EXIT_SUCCESS;
}
```

---

#### pthread_mutex_init()

> int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)

**初始化互斥锁。**

该服务使用互斥锁属性对象 `attr` 初始化互斥锁 `mutex`。如果 `attr` 为 NULL，则使用默认属性（参见 `pthread_mutexattr_init()`）。

**参数:**
- `mutex` - 要初始化的互斥锁；
- `attr` - 互斥锁属性对象。

**返回值:**
- 成功时返回 `0`。
- 出错时返回错误号：
    - `EINVAL`，互斥锁属性对象 `attr` 无效或未初始化；
    - `EBUSY`，互斥锁 `mutex` 已经初始化；
    - `ENOMEM`，系统堆中没有足够的内存来初始化互斥锁，请增加 `CONFIG_XENO_OPT_SYS_HEAPSZ`；
    - `EAGAIN`，没有足够的内存来初始化互斥锁，对于进程共享的互斥锁，请增加 `CONFIG_XENO_OPT_SHARED_HEAPSZ`，对于进程私有的互斥锁，请增加 `CONFIG_XENO_OPT_PRIVATE_HEAPSZ`；
    - `EAGAIN`，没有可用的注册槽，请检查/增加 `CONFIG_XENO_OPT_REGISTRY_NRSLOTS`；
    - `ENOSYS`，`attr` 提到优先级保护（`PTHREAD_PRIO_PROTECT`），但 C 库不提供 `pthread_mutexattr_get/setprioceiling()`。

**标签:** `thread-unrestricted`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 5

pthread_mutex_t mutex;
int shared_counter = 0;

void* increment_counter(void* arg) {
    for (int i = 0; i < 100000; i++) {
        pthread_mutex_lock(&mutex);
        shared_counter++;  // 访问共享资源
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];

    // 初始化互斥锁
    if (pthread_mutex_init(&mutex, NULL) != 0) {
        perror("Mutex initialization failed");
        return EXIT_FAILURE;
    }

    // 创建多个线程
    for (int i = 0; i < NUM_THREADS; i++) {
        if (pthread_create(&threads[i], NULL, increment_counter, NULL) != 0) {
            perror("Thread creation failed");
            return EXIT_FAILURE;
        }
    }

    // 等待所有线程完成
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }

    printf("Final counter value: %d\n", shared_counter);

    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return EXIT_SUCCESS;
}
```

---

#### pthread_mutex_setprioceiling()

> int pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling, int *old_ceiling)

设置互斥锁的优先级上限。

该例程获取指定的互斥锁，然后更改关联的优先级上限值并释放它。**prioceiling** 必须在 `sched_get_priority_min()` 和 `sched_get_priority_max()` 返回的值之间（包括这些值）。

Cobalt 实现在此操作期间使用先前的上限值应用优先级上限协议。新的优先级上限将在下次互斥锁从未锁定状态转换为锁定状态时生效。

**参数**:
- **mutex**: 目标互斥锁。
- **prioceiling**: 新的上限值。
- **old_ceiling**: 成功时，如果该参数非 NULL，先前的上限值将被复制到此地址。

**返回值**:
- 成功时返回 **0**。
- 出错时返回错误号：
    - **EPERM**: 调用者无权执行该操作；
    - **EINVAL**: `mutex` 无效；
    - **EINVAL**: `mutex` 不是 `PTHREAD_PRIO_PROTECT` 类型；
    - **EINVAL**: `prioceiling` 超出范围。

**注意**:
如果调用线程的优先级高于互斥锁的新优先级上限，该操作仍将成功；Cobalt 内核从不降低锁定优先级保护互斥锁的线程的有效优先级。

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 5

pthread_mutex_t mutex;
int shared_counter = 0;

void* increment_counter(void* arg) {
    for (int i = 0; i < 100000; i++) {
        if(!pthread_mutex_trylock(&mutex)) {
            shared_counter++;  // 访问共享资源
            pthread_mutex_unlock(&mutex);
        }
    }
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];
    int old_priority = 0;
    int new_priority = 50; // 设置的新优先级

    // 初始化互斥锁
    if (pthread_mutex_init(&mutex, NULL) != 0) {
        perror("Mutex initialization failed");
        return EXIT_FAILURE;
    }

     // 设置互斥锁的优先级上限
    if (pthread_mutex_setprioceiling(&mutex, new_priority, &old_priority) != 0) {
        perror("pthread_mutex_setprioceiling");
        return EXIT_FAILURE;
    }
    printf("New priority: %d, Old priority: %d\n",new_priority,old_priority);
    // 创建多个线程
    for (int i = 0; i < NUM_THREADS; i++) {
        if (pthread_create(&threads[i], NULL, increment_counter, NULL) != 0) {
            perror("Thread creation failed");
            return EXIT_FAILURE;
        }
    }

    // 等待所有线程完成
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    // shared_counter != 500000
    printf("Final counter value: %d\n", shared_counter);

    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return EXIT_SUCCESS;
}
```

---

#### pthread_mutex_trylock()

> int pthread_mutex_trylock (pthread_mutex_t *mutex)

尝试锁定互斥锁。

该服务等效于 `pthread_mutex_lock()`，但如果互斥锁 **mx** 被当前线程以外的其他线程锁定，该服务会立即返回。

**参数**:
- **mutex**: 要锁定的互斥锁。

**返回值**:
- 成功时返回 **0**。
- 出错时返回错误号：
    - **EPERM**: 调用者无权执行该操作；
    - **EINVAL**: 互斥锁无效；
    - **EPERM**: 互斥锁不是进程共享的，并且不属于当前进程；
    - **EBUSY**: 互斥锁已被当前线程以外的其他线程锁定；
    - **EAGAIN**: 互斥锁是递归的，并且已超过最大递归锁定次数。

**标签**:
- `xthread-only`, `switch-primary`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 5

pthread_mutex_t mutex;
int shared_counter = 0;

void* increment_counter(void* arg) {
    for (int i = 0; i < 100000; i++) {
        if(!pthread_mutex_trylock(&mutex)) {
            shared_counter++;  // 访问共享资源
            pthread_mutex_unlock(&mutex);
        }
    }
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];

    // 初始化互斥锁
    if (pthread_mutex_init(&mutex, NULL) != 0) {
        perror("Mutex initialization failed");
        return EXIT_FAILURE;
    }

    // 创建多个线程
    for (int i = 0; i < NUM_THREADS; i++) {
        if (pthread_create(&threads[i], NULL, increment_counter, NULL) != 0) {
            perror("Thread creation failed");
            return EXIT_FAILURE;
        }
    }

    // 等待所有线程完成
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    // shared_counter != 500000
    printf("Final counter value: %d\n", shared_counter);

    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return EXIT_SUCCESS;
}
```

---

#### pthread_mutex_unlock()

> int pthread_mutex_unlock (pthread_mutex_t *mutex)

解锁互斥锁。

该服务解锁 **mutex**。如果 **mutex** 是 `PTHREAD_MUTEX_RECURSIVE` 类型且锁定递归计数大于一，则锁定递归计数递减，互斥锁保持锁定状态。

尝试解锁未锁定的互斥锁或被其他线程锁定的互斥锁会产生 **EPERM** 错误，无论互斥锁的 **type** 属性如何。

**参数**:
- **mutex**: 要释放的互斥锁。

**返回值**:
- 成功时返回 **0**。
- 出错时返回错误号：
    - **EPERM**: 调用者无权执行该操作；
    - **EINVAL**: 互斥锁 **mutex** 无效；
    - **EPERM**: 互斥锁未被当前线程锁定。

**标签**:
- `xthread-only`, `switch-primary`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 5

pthread_mutex_t mutex;
int shared_counter = 0;

void* increment_counter(void* arg) {
    for (int i = 0; i < 100000; i++) {
        pthread_mutex_lock(&mutex);
        shared_counter++;  // 访问共享资源
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];

    // 初始化互斥锁
    if (pthread_mutex_init(&mutex, NULL) != 0) {
        perror("Mutex initialization failed");
        return EXIT_FAILURE;
    }

    // 创建多个线程
    for (int i = 0; i < NUM_THREADS; i++) {
        if (pthread_create(&threads[i], NULL, increment_counter, NULL) != 0) {
            perror("Thread creation failed");
            return EXIT_FAILURE;
        }
    }

    // 等待所有线程完成
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }

    printf("Final counter value: %d\n", shared_counter);

    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return EXIT_SUCCESS;
}
```

---

#### pthread_mutexattr_destroy()

> int pthread_mutexattr_destroy (pthread_mutexattr_t *attr)

销毁互斥锁属性对象。

该服务销毁互斥锁属性对象 **attr**。该对象对于所有互斥锁服务（除了 `pthread_mutexattr_init()`）都变为无效（它们都会返回 **EINVAL**）。

**参数**:
- **attr**: 要销毁的已初始化的互斥锁属性对象。

**返回值**:
- 成功时返回 **0**。
- 出错时返回错误号：
    - **EINVAL**: 互斥锁属性对象 **attr** 无效。

**标签**:
- `thread-unrestricted`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

int main() {
    pthread_mutex_t mutex;
    pthread_mutexattr_t attr;
    int protocol;
    int ret;

    // 初始化互斥锁属性
    if (pthread_mutexattr_init(&attr) != 0) {
        perror("pthread_mutexattr_init");
        exit(EXIT_FAILURE);
    }

    // 设置互斥锁为优先级继承
    if (pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT) != 0) {
        perror("pthread_mutexattr_setprotocol");
        exit(EXIT_FAILURE);
    }

    // 初始化互斥锁
    if (pthread_mutex_init(&mutex, &attr) != 0) {
        perror("pthread_mutex_init");
        exit(EXIT_FAILURE);
    }

    // 销毁互斥锁
    if (pthread_mutex_destroy(&mutex) != 0) {
        perror("pthread_mutex_destroy");
        exit(EXIT_FAILURE);
    }

    // 销毁互斥锁属性
    if (pthread_mutexattr_destroy(&attr) != 0) {
        perror("pthread_mutexattr_destroy");
        exit(EXIT_FAILURE);
    }

    return 0;
}
```

---

#### pthread_mutexattr_getprotocol()

> int pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attr, int *proto)

从互斥锁属性对象中获取协议属性。

该服务将互斥锁属性对象 **attr** 中 **protocol** 属性的值存储在 **proto** 地址处。

**protocol** 属性可以是 **PTHREAD_PRIO_NONE**、**PTHREAD_PRIO_INHERIT** 或 **PTHREAD_PRIO_PROTECT** 之一。有关这些常量的含义，请参见 `pthread_mutexattr_setprotocol()`。

**参数**:
- **attr**: 已初始化的互斥锁属性对象。
- **proto**: 成功时存储协议属性值的地址。

**返回值**:
- 成功时返回 **0**。
- 出错时返回错误号：
    - **EINVAL**: **proto** 地址无效；
    - **EINVAL**: 互斥锁属性对象 **attr** 无效。

**标签**:
- `thread-unrestricted`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

int main() {
    pthread_mutex_t mutex;
    pthread_mutexattr_t attr;
    int protocol;
    int ret;

    // 初始化互斥锁属性
    if (pthread_mutexattr_init(&attr) != 0) {
        perror("pthread_mutexattr_init");
        exit(EXIT_FAILURE);
    }

    // 设置互斥锁为优先级继承
    if (pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT) != 0) {
        perror("pthread_mutexattr_setprotocol");
        exit(EXIT_FAILURE);
    }

    // 初始化互斥锁
    if (pthread_mutex_init(&mutex, &attr) != 0) {
        perror("pthread_mutex_init");
        exit(EXIT_FAILURE);
    }

    // 获取互斥锁协议
    ret = pthread_mutexattr_getprotocol(&attr, &protocol);
    if (ret != 0) {
        perror("pthread_mutexattr_getprotocol");
        exit(EXIT_FAILURE);
    }
    // 输出协议类型
    switch (protocol) {
        case PTHREAD_PRIO_NONE:
            printf("Mutex protocol: PTHREAD_PRIO_NONE\n");
            break;
        case PTHREAD_PRIO_INHERIT:
            printf("Mutex protocol: PTHREAD_PRIO_INHERIT\n");
            break;
        case PTHREAD_PRIO_PROTECT:
            printf("Mutex protocol: PTHREAD_PRIO_PROTECT\n");
            break;
        default:
            printf("Unknown mutex protocol\n");
            break;
    }

    // 销毁互斥锁
    if (pthread_mutex_destroy(&mutex) != 0) {
        perror("pthread_mutex_destroy");
        exit(EXIT_FAILURE);
    }

    // 销毁互斥锁属性
    if (pthread_mutexattr_destroy(&attr) != 0) {
        perror("pthread_mutexattr_destroy");
        exit(EXIT_FAILURE);
    }

    return 0;
}
```

---

#### pthread_mutexattr_getpshared()

> int pthread_mutexattr_getpshared (const pthread_mutexattr_t *attr, int *pshared)

获取互斥锁属性对象的进程共享属性。

该服务将互斥锁属性对象 **attr** 中 **pshared** 属性的值存储在 **pshared** 地址处。

**pshared** 属性只能是 **PTHREAD_PROCESS_PRIVATE** 或 **PTHREAD_PROCESS_SHARED** 之一。有关这两个常量的含义，请参见 `pthread_mutexattr_setpshared()`。

**参数**:
- **attr**: 已初始化的互斥锁属性对象。
- **pshared**: 成功时存储 **pshared** 属性值的地址。

**返回值**:
- 成功时返回 **0**。
- 出错时返回错误号：
    - **EINVAL**: **pshared** 地址无效；
    - **EINVAL**: 互斥锁属性对象 **attr** 无效。

**标签**:
- `thread-unrestricted`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

int main() {
    pthread_mutex_t mutex;
    pthread_mutexattr_t attr;
    int shared;
    int ret;

    // 初始化互斥锁属性
    if (pthread_mutexattr_init(&attr) != 0) {
        perror("pthread_mutexattr_init");
        exit(EXIT_FAILURE);
    }

    // 设置互斥锁为进程共享类型
    ret = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    if (ret != 0) {
        perror("pthread_mutexattr_setpshared");
        exit(EXIT_FAILURE);
    }

    // 初始化互斥锁
    ret = pthread_mutex_init(&mutex, &attr);
    if (ret != 0) {
        perror("pthread_mutex_init");
        exit(EXIT_FAILURE);
    }

    // 获取互斥锁共享属性
    ret = pthread_mutexattr_getpshared(&attr, &shared);
    if (ret != 0) {
        perror("pthread_mutexattr_getpshared");
        exit(EXIT_FAILURE);
    }

    // 输出互斥锁共享属性
    if (shared == PTHREAD_PROCESS_SHARED) {
        printf("Mutex is shared between processes.\n");
    } else {
        printf("Mutex is shared between threads only.\n");
    }

    // 销毁互斥锁
    ret = pthread_mutex_destroy(&mutex);
    if (ret != 0) {
        perror("pthread_mutex_destroy");
        exit(EXIT_FAILURE);
    }

    // 销毁互斥锁属性
    ret = pthread_mutexattr_destroy(&attr);
    if (ret != 0) {
        perror("pthread_mutexattr_destroy");
        exit(EXIT_FAILURE);
    }

    return 0;
}
```

---

#### pthread_mutexattr_gettype()

> int pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *type)

获取互斥锁属性对象的类型属性。

该服务将互斥锁属性对象 **attr** 中 **type** 属性的值存储在 **type** 地址处。

有关 **type** 属性值及其对互斥锁的影响，请参见 `pthread_mutex_lock()` 和 `pthread_mutex_unlock()`。

**参数**:
- **attr**: 已初始化的互斥锁属性对象。
- **type**: 成功时存储 **type** 属性值的地址。

**返回值**:
- 成功时返回 **0**。
- 出错时返回错误号：
    - **EINVAL**: **type** 地址无效；
    - **EINVAL**: 互斥锁属性对象 **attr** 无效。

**标签**:
- `thread-unrestricted`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

int main() {
    pthread_mutex_t mutex;
    pthread_mutexattr_t attr;
    int mutex_type;
    int ret;

    // 初始化互斥锁属性
    if (pthread_mutexattr_init(&attr) != 0) {
        perror("pthread_mutexattr_init");
        exit(EXIT_FAILURE);
    }

    // 设置互斥锁为递归类型
    ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    if (ret != 0) {
        perror("pthread_mutexattr_settype");
        exit(EXIT_FAILURE);
    }

    // 初始化互斥锁
    ret = pthread_mutex_init(&mutex, &attr);
    if (ret != 0) {
        perror("pthread_mutex_init");
        exit(EXIT_FAILURE);
    }

    // 获取互斥锁类型
    ret = pthread_mutexattr_gettype(&attr, &mutex_type);
    if (ret != 0) {
        perror("pthread_mutexattr_gettype");
        exit(EXIT_FAILURE);
    }

    // 输出互斥锁类型
    switch (mutex_type) {
        case PTHREAD_MUTEX_NORMAL:
            printf("Mutex type: PTHREAD_MUTEX_NORMAL\n");
            break;
        case PTHREAD_MUTEX_RECURSIVE:
            printf("Mutex type: PTHREAD_MUTEX_RECURSIVE\n");
            break;
        case PTHREAD_MUTEX_ERRORCHECK:
            printf("Mutex type: PTHREAD_MUTEX_ERRORCHECK\n");
            break;
        default:
            printf("Unknown mutex type\n");
            break;
    }

    // 销毁互斥锁
    ret = pthread_mutex_destroy(&mutex);
    if (ret != 0) {
        perror("pthread_mutex_destroy");
        exit(EXIT_FAILURE);
    }

    // 销毁互斥锁属性
    ret = pthread_mutexattr_destroy(&attr);
    if (ret != 0) {
        perror("pthread_mutexattr_destroy");
        exit(EXIT_FAILURE);
    }

    return 0;
}
```

---

#### pthread_mutexattr_init()

> int pthread_mutexattr_init (pthread_mutexattr_t *attr)

初始化互斥锁属性对象。

该服务使用所有属性的默认值初始化互斥锁属性对象 **attr**。默认值为：
- 对于 **type** 属性，`PTHREAD_MUTEX_NORMAL`；
- 对于 **protocol** 属性，`PTHREAD_PRIO_NONE`；
- 对于 **pshared** 属性，`PTHREAD_PROCESS_PRIVATE`。

如果在已经初始化的互斥锁属性对象上调用此服务，则该属性对象将被重新初始化。

**参数**:
- **attr**: 要初始化的互斥锁属性对象。

**返回值**:
- 成功时返回 **0**。
- 出错时返回错误号：
    - **ENOMEM**: 互斥锁属性对象指针 **attr** 为 NULL。

**标签**:
- `thread-unrestricted`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

int main() {
    pthread_mutex_t mutex;
    pthread_mutexattr_t attr;
    int protocol;
    int ret;

    // 初始化互斥锁属性
    if (pthread_mutexattr_init(&attr) != 0) {
        perror("pthread_mutexattr_init");
        exit(EXIT_FAILURE);
    }

    // 设置互斥锁为优先级继承
    if (pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT) != 0) {
        perror("pthread_mutexattr_setprotocol");
        exit(EXIT_FAILURE);
    }

    // 初始化互斥锁
    if (pthread_mutex_init(&mutex, &attr) != 0) {
        perror("pthread_mutex_init");
        exit(EXIT_FAILURE);
    }

    // 销毁互斥锁
    if (pthread_mutex_destroy(&mutex) != 0) {
        perror("pthread_mutex_destroy");
        exit(EXIT_FAILURE);
    }

    // 销毁互斥锁属性
    if (pthread_mutexattr_destroy(&attr) != 0) {
        perror("pthread_mutexattr_destroy");
        exit(EXIT_FAILURE);
    }

    return 0;
}
```

---

#### pthread_mutexattr_setprotocol()

> int pthread_mutexattr_setprotocol (pthread_mutexattr_t *attr, int proto)

设置互斥锁属性对象的协议属性。

该服务设置互斥锁属性对象 **attr** 的 **protocol** 属性。

**参数**:
- **attr**: 已初始化的互斥锁属性对象。
- **proto**: **protocol** 属性的值，可以是以下之一：
    - `PTHREAD_PRIO_NONE`: 表示使用属性对象 **attr** 创建的互斥锁将不遵循任何优先级协议。
    - `PTHREAD_PRIO_INHERIT`: 表示使用属性对象 **attr** 创建的互斥锁将遵循优先级继承协议。
    - `PTHREAD_PRIO_PROTECT`: 表示使用属性对象 **attr** 创建的互斥锁将遵循优先级保护协议。

**返回值**:
- 成功时返回 **0**。
- 出错时返回错误号：
    - **EINVAL**: 互斥锁属性对象 **attr** 无效。
    - **ENOTSUP**: **proto** 的值不受支持。
    - **EINVAL**: **proto** 的值无效。

**标签**:
- `thread-unrestricted`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

int main() {
    pthread_mutex_t mutex;
    pthread_mutexattr_t attr;
    int protocol;
    int ret;

    // 初始化互斥锁属性
    if (pthread_mutexattr_init(&attr) != 0) {
        perror("pthread_mutexattr_init");
        exit(EXIT_FAILURE);
    }

    ret = pthread_mutexattr_getprotocol(&attr, &protocol);
    if (ret != 0) {
        perror("pthread_mutexattr_getprotocol");
        exit(EXIT_FAILURE);
    }
    printf("Before SetProtocol: %d\n", protocol);
    // 设置互斥锁为优先级继承
    ret = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
    if (ret != 0) {
        perror("pthread_mutexattr_setprotocol");
        exit(EXIT_FAILURE);
    }

    // 初始化互斥锁
    ret = pthread_mutex_init(&mutex, &attr);
    if (ret != 0) {
        perror("pthread_mutex_init");
        exit(EXIT_FAILURE);
    }
    ret = pthread_mutexattr_getprotocol(&attr, &protocol);
    if (ret != 0) {
        perror("pthread_mutexattr_getprotocol");
        exit(EXIT_FAILURE);
    }
    printf("After SetProtocol: %d\n", protocol);

    // 销毁互斥锁
    ret = pthread_mutex_destroy(&mutex);
    if (ret != 0) {
        perror("pthread_mutex_destroy");
        exit(EXIT_FAILURE);
    }

    // 销毁互斥锁属性
    ret = pthread_mutexattr_destroy(&attr);
    if (ret != 0) {
        perror("pthread_mutexattr_destroy");
        exit(EXIT_FAILURE);
    }

    return 0;
}

```

---

#### pthread_mutexattr_setpshared()

> int pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared)

设置互斥锁属性对象的进程共享属性。

该服务设置互斥锁属性对象 **attr** 的 **pshared** 属性。

**参数**:
- **attr**: 已初始化的互斥锁属性对象。
- **pshared**: **pshared** 属性的值，可以是以下之一：
    - `PTHREAD_PROCESS_PRIVATE`: 表示使用属性对象 **attr** 创建的互斥锁仅可被初始化该互斥锁的线程所在的同一进程内的线程访问。
    - `PTHREAD_PROCESS_SHARED`: 表示使用属性对象 **attr** 创建的互斥锁可被任何访问该互斥锁所在内存的线程访问。

**返回值**:
- 成功时返回 **0**。
- 出错时返回错误号：
    - **EINVAL**: 互斥锁属性对象 **attr** 无效。
    - **EINVAL**: **pshared** 的值无效。

**标签**:
- `thread-unrestricted`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

int main() {
    pthread_mutex_t mutex;
    pthread_mutexattr_t attr;
    int shared;
    int ret;

    // 初始化互斥锁属性
    if (pthread_mutexattr_init(&attr) != 0) {
        perror("pthread_mutexattr_init");
        exit(EXIT_FAILURE);
    }

    ret = pthread_mutexattr_getpshared(&attr, &shared);
    if (ret != 0) {
        perror("pthread_mutexattr_getpshared");
        exit(EXIT_FAILURE);
    }
    printf("Before SetShared: %d\n", shared);
    // 设置互斥锁为进程共享类型
    ret = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    if (ret != 0) {
        perror("pthread_mutexattr_setpshared");
        exit(EXIT_FAILURE);
    }

    // 初始化互斥锁
    ret = pthread_mutex_init(&mutex, &attr);
    if (ret != 0) {
        perror("pthread_mutex_init");
        exit(EXIT_FAILURE);
    }

    // 获取互斥锁共享属性
    ret = pthread_mutexattr_getpshared(&attr, &shared);
    if (ret != 0) {
        perror("pthread_mutexattr_getpshared");
        exit(EXIT_FAILURE);
    }
    printf("After SetShared: %d\n", shared);  

    // 销毁互斥锁
    ret = pthread_mutex_destroy(&mutex);
    if (ret != 0) {
        perror("pthread_mutex_destroy");
        exit(EXIT_FAILURE);
    }

    // 销毁互斥锁属性
    ret = pthread_mutexattr_destroy(&attr);
    if (ret != 0) {
        perror("pthread_mutexattr_destroy");
        exit(EXIT_FAILURE);
    }

    return 0;
}
```

---

#### pthread_mutexattr_settype()

> int pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type)

设置互斥锁属性对象的类型属性。

该服务设置互斥锁属性对象 **attr** 的 **type** 属性。

有关 **type** 属性值及其对互斥锁的影响，请参见 `pthread_mutex_lock()` 和 `pthread_mutex_unlock()`。

`PTHREAD_MUTEX_DEFAULT` 默认 **type** 与 `PTHREAD_MUTEX_NORMAL` 相同。请注意，使用递归的 Cobalt 互斥锁与 Cobalt 条件变量是安全的（参见 `pthread_cond_wait()` 文档）。

**参数**:
- **attr**: 已初始化的互斥锁属性对象。
- **type**: **type** 属性的值。

**返回值**:
- 成功时返回 **0**。
- 出错时返回错误号：
    - **EINVAL**: 互斥锁属性对象 **attr** 无效。
    - **EINVAL**: **type** 属性的值无效。

**标签**:
- `thread-unrestricted`

示例代码

```c{filename="app.c"}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

int main() {
    pthread_mutex_t mutex;
    pthread_mutexattr_t attr;
    int mutex_type;
    int ret;

    // 初始化互斥锁属性
    if (pthread_mutexattr_init(&attr) != 0) {
        perror("pthread_mutexattr_init");
        exit(EXIT_FAILURE);
    }

    ret = pthread_mutexattr_gettype(&attr, &mutex_type);
    if (ret != 0) {
        perror("pthread_mutexattr_gettype");
        exit(EXIT_FAILURE);
    }
    printf("Before SetType: %d\n", mutex_type);
    // 设置互斥锁为递归类型
    ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    if (ret != 0) {
        perror("pthread_mutexattr_settype");
        exit(EXIT_FAILURE);
    }

    // 初始化互斥锁
    ret = pthread_mutex_init(&mutex, &attr);
    if (ret != 0) {
        perror("pthread_mutex_init");
        exit(EXIT_FAILURE);
    }

    // 获取互斥锁类型
    ret = pthread_mutexattr_gettype(&attr, &mutex_type);
    if (ret != 0) {
        perror("pthread_mutexattr_gettype");
        exit(EXIT_FAILURE);
    }
    printf("After SetType: %d\n", mutex_type);

    // 销毁互斥锁
    ret = pthread_mutex_destroy(&mutex);
    if (ret != 0) {
        perror("pthread_mutex_destroy");
        exit(EXIT_FAILURE);
    }

    // 销毁互斥锁属性
    ret = pthread_mutexattr_destroy(&attr);
    if (ret != 0) {
        perror("pthread_mutexattr_destroy");
        exit(EXIT_FAILURE);
    }

    return 0;
}
```

---