# Cobalt/Condition variables

### 详细描述

Cobalt/POSIX 条件变量服务。

条件变量是一种同步对象，允许线程挂起执行，直到共享数据上的某个谓词得到满足。条件变量的基本操作包括：当谓词变为真时发出信号，以及等待条件，挂起线程执行直到另一个线程发出条件信号。

条件变量必须始终与互斥锁关联，以避免线程准备等待条件变量时，另一个线程在第一个线程实际等待之前发出条件信号的竞争条件。

在使用之前，必须使用 `pthread_cond_init()` 初始化条件变量。可以传递给此服务的属性对象允许选择创建的条件变量的特性，即 `pthread_cond_timedwait()` 服务使用的时钟（默认使用 `CLOCK_REALTIME`），以及是否可以在多个进程之间共享（默认情况下不能共享，参见 `pthread_condattr_setpshared()`）。

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

### 函数文档

#### pthread_cond_timedwait

> int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);

在条件变量上等待指定时间。

该服务等同于 `pthread_cond_wait()`，但调用线程仅在条件变量 `cond` 上阻塞，直到 `abstime` 指定的超时时间到期。

超时时间 `abstime` 表示为传递给 `pthread_cond_init()` 的 `clock` 属性的绝对值。默认情况下，使用 `CLOCK_REALTIME`。

参数:

- `cond`: 要等待的条件变量；
- `mutex`: 与 `cond` 关联的互斥锁；
- `abstime`: 超时时间，表示为传递给 `pthread_cond_init()` 的时钟属性的绝对值。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `EPERM`，调用者上下文无效；
  - `EPERM`，指定的条件变量不是进程共享的，并且不属于当前进程；
  - `EINVAL`，指定的条件变量、互斥锁或超时时间无效；
  - `EINVAL`，另一个线程当前使用与 `mutex` 不同的互斥锁阻塞在 `cond` 上；
  - `EPERM`，指定的互斥锁不属于调用者；
  - `ETIMEDOUT`，指定的超时时间已到期。

标签:

- `xthread-only`，`switch-primary`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    #include <errno.h>

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond;
    int ready = 0;

    void* worker(void* arg) {
        struct timespec ts;
        int rc;
        // 获取当前时间
        clock_gettime(CLOCK_REALTIME, &ts);
        // 设置超时时间为当前时间加5秒
        ts.tv_sec += 5;

        pthread_mutex_lock(&mutex);
        while (!ready) {
            printf("Worker: Waiting for signal (with timeout)...\n");
            rc = pthread_cond_timedwait(&cond, &mutex, &ts);
            if (rc == ETIMEDOUT) {
                printf("Worker: Timeout occurred, no signal received.\n");
                pthread_mutex_unlock(&mutex);
                return NULL;
            } else if (rc != 0) {
                perror("pthread_cond_timedwait");
                pthread_mutex_unlock(&mutex);
                return NULL;
            }
        }
        printf("Worker: Signal received, ready = %d\n", ready);
        pthread_mutex_unlock(&mutex);
        return NULL;
    }

    int main() {
        pthread_t thread;
        int rc;
        pthread_cond_init(&cond, NULL);
        rc = pthread_create(&thread, NULL, worker, NULL);
        if (rc != 0) {
            perror("pthread_create");
            return 1;
        }

        // 主线程睡眠2秒，然后发送信号
        sleep(2);

        pthread_mutex_lock(&mutex);
        ready = 1;
        printf("Main: Sending signal\n");
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);

        pthread_join(thread, NULL);
        pthread_cond_destroy(&cond);
        return 0;
    }

#### pthread_cond_broadcast()

> int pthread_cond_broadcast(pthread_cond_t *cond)

广播条件变量。

该服务解除所有在条件变量 `cond` 上阻塞的线程的阻塞状态。

参数:

- `cond`: 要发出信号的条件变量。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `EINVAL`，条件变量无效；
  - `EPERM`，条件变量不是进程共享的，并且不属于当前进程。

标签:

- `xthread-only`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    #include <errno.h>

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond;
    int ready = 0;

    void* worker(void* arg) {
        struct timespec ts;
        int rc;
        // 获取当前时间
        clock_gettime(CLOCK_REALTIME, &ts);
        // 设置超时时间为当前时间加5秒
        ts.tv_sec += 5;

        pthread_mutex_lock(&mutex);
        while (!ready) {
            printf("Worker: Waiting for signal (with timeout)...\n");
            rc = pthread_cond_timedwait(&cond, &mutex, &ts);
            if (rc == ETIMEDOUT) {
                printf("Worker: Timeout occurred, no signal received.\n");
                pthread_mutex_unlock(&mutex);
                return NULL;
            } else if (rc != 0) {
                perror("pthread_cond_timedwait");
                pthread_mutex_unlock(&mutex);
                return NULL;
            }
        }
        printf("Worker: Signal received, ready = %d\n", ready);
        pthread_mutex_unlock(&mutex);
        return NULL;
    }

    int main() {
        pthread_t thread1, thread2;
        int rc;
        pthread_cond_init(&cond, NULL);
        rc = pthread_create(&thread1, NULL, worker, NULL);
        if (rc != 0) {
            perror("pthread_create");
            return 1;
        }
        rc = pthread_create(&thread2, NULL, worker, NULL);
        if (rc != 0) {
            perror("pthread_create");
            return 1;
        }

        // 主线程睡眠2秒，然后发送信号
        sleep(2);

        pthread_mutex_lock(&mutex);
        ready = 2;
        printf("Main: Sending signal\n");
        pthread_cond_broadcast(&cond);
        pthread_mutex_unlock(&mutex);

        pthread_join(thread1, NULL);
        pthread_join(thread2, NULL);
        pthread_cond_destroy(&cond);
        return 0;
    }

#### pthread_cond_destroy()

> int pthread_cond_destroy(pthread_cond_t *cond)

销毁条件变量。

该服务销毁条件变量 `cond`，前提是没有线程当前阻塞在其上。条件变量对于所有条件变量服务变为无效（它们都返回 `EINVAL` 错误），除了 `pthread_cond_init()`。

参数:

- `cond`: 要销毁的条件变量。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `EINVAL`，条件变量 `cond` 无效；
  - `EPERM`，条件变量不是进程共享的，并且不属于当前进程；
  - `EBUSY`，某些线程当前正在使用该条件变量。

标签:

- `thread-unrestricted`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    #include <errno.h>

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond;
    int ready = 0;

    void* worker(void* arg) {
        struct timespec ts;
        int rc;
        // 获取当前时间
        clock_gettime(CLOCK_REALTIME, &ts);
        // 设置超时时间为当前时间加5秒
        ts.tv_sec += 5;

        pthread_mutex_lock(&mutex);
        while (!ready) {
            printf("Worker: Waiting for signal (with timeout)...\n");
            rc = pthread_cond_timedwait(&cond, &mutex, &ts);
            if (rc == ETIMEDOUT) {
                printf("Worker: Timeout occurred, no signal received.\n");
                pthread_mutex_unlock(&mutex);
                return NULL;
            } else if (rc != 0) {
                perror("pthread_cond_timedwait");
                pthread_mutex_unlock(&mutex);
                return NULL;
            }
        }
        printf("Worker: Signal received, ready = %d\n", ready);
        pthread_mutex_unlock(&mutex);
        return NULL;
    }

    int main() {
        pthread_t thread;
        int rc;
        pthread_cond_init(&cond, NULL);
        rc = pthread_create(&thread, NULL, worker, NULL);
        if (rc != 0) {
            perror("pthread_create");
            return 1;
        }

        // 主线程睡眠2秒，然后发送信号
        sleep(2);

        pthread_mutex_lock(&mutex);
        ready = 3;
        printf("Main: Sending signal\n");
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);

        pthread_join(thread, NULL);
        pthread_cond_destroy(&cond);
        return 0;
    }

#### pthread_cond_init()

> int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)

初始化条件变量。

该服务使用条件变量属性对象 `attr` 初始化条件变量 `cond`。如果 `attr` 为 `NULL`，则使用默认属性（参见 `pthread_condattr_init()`）。

参数:

- `cond`: 要初始化的条件变量；
- `attr`: 条件变量属性对象。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `EINVAL`，条件变量属性对象 `attr` 无效或未初始化；
  - `EBUSY`，条件变量 `cond` 已经初始化；
  - `ENOMEM`，系统堆内存不足以初始化条件变量，请增加 `CONFIG_XENO_OPT_SYS_HEAPSZ`；
  - `EAGAIN`，没有可用的注册槽，请检查/增加 `CONFIG_XENO_OPT_REGISTRY_NRSLOTS`。

标签:

- `thread-unrestricted`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    #include <errno.h>

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond;
    int ready = 0;

    void* worker(void* arg) {
        struct timespec ts;
        int rc;
        // 获取当前时间
        clock_gettime(CLOCK_REALTIME, &ts);
        // 设置超时时间为当前时间加5秒
        ts.tv_sec += 5;

        pthread_mutex_lock(&mutex);
        while (!ready) {
            printf("Worker: Waiting for signal (with timeout)...\n");
            rc = pthread_cond_timedwait(&cond, &mutex, &ts);
            if (rc == ETIMEDOUT) {
                printf("Worker: Timeout occurred, no signal received.\n");
                pthread_mutex_unlock(&mutex);
                return NULL;
            } else if (rc != 0) {
                perror("pthread_cond_timedwait");
                pthread_mutex_unlock(&mutex);
                return NULL;
            }
        }
        printf("Worker: Signal received, ready = %d\n", ready);
        pthread_mutex_unlock(&mutex);
        return NULL;
    }

    int main() {
        pthread_t thread;
        int rc;
        pthread_cond_init(&cond, NULL);
        rc = pthread_create(&thread, NULL, worker, NULL);
        if (rc != 0) {
            perror("pthread_create");
            return 1;
        }

        // 主线程睡眠2秒，然后发送信号
        sleep(2);

        pthread_mutex_lock(&mutex);
        ready = 4;
        printf("Main: Sending signal\n");
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);

        pthread_join(thread, NULL);
        pthread_cond_destroy(&cond);
        return 0;
    }

#### pthread_cond_signal()

> int pthread_cond_signal(pthread_cond_t *cond)

发出条件变量信号。

该服务解除一个在条件变量 `cond` 上阻塞的线程的阻塞状态。

如果有多个线程阻塞在指定的条件变量上，则优先级最高的线程将被解除阻塞。

参数:

- `cond`: 要发出信号的条件变量。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `EINVAL`，条件变量无效；
  - `EPERM`，条件变量不是进程共享的，并且不属于当前进程。

标签:

- `xthread-only`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    #include <errno.h>

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond;
    int ready = 0;

    void* worker(void* arg) {
        struct timespec ts;
        int rc;
        // 获取当前时间
        clock_gettime(CLOCK_REALTIME, &ts);
        // 设置超时时间为当前时间加5秒
        ts.tv_sec += 5;

        pthread_mutex_lock(&mutex);
        while (!ready) {
            printf("Worker: Waiting for signal (with timeout)...\n");
            rc = pthread_cond_timedwait(&cond, &mutex, &ts);
            if (rc == ETIMEDOUT) {
                printf("Worker: Timeout occurred, no signal received.\n");
                pthread_mutex_unlock(&mutex);
                return NULL;
            } else if (rc != 0) {
                perror("pthread_cond_timedwait");
                pthread_mutex_unlock(&mutex);
                return NULL;
            }
        }
        printf("Worker: Signal received, ready = %d\n", ready);
        pthread_mutex_unlock(&mutex);
        return NULL;
    }

    int main() {
        pthread_t thread;
        int rc;
        pthread_cond_init(&cond, NULL);
        rc = pthread_create(&thread, NULL, worker, NULL);
        if (rc != 0) {
            perror("pthread_create");
            return 1;
        }

        // 主线程睡眠2秒，然后发送信号
        sleep(2);

        pthread_mutex_lock(&mutex);
        ready = 5;
        printf("Main: Sending signal\n");
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);

        pthread_join(thread, NULL);
        pthread_cond_destroy(&cond);
        return 0;
    }

#### pthread_cond_wait()

> int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)

等待条件变量。

该服务原子性地解锁互斥锁 `mutex`，并阻塞调用线程，直到条件变量 `cond` 被 `pthread_cond_signal()` 或 `pthread_cond_broadcast()` 发出信号。当条件被发出信号时，该服务在返回之前重新获取互斥锁。

如果阻塞线程接收到信号，则会发生虚假唤醒，因此应用程序不应假设在该服务成功返回时条件已更改。

即使互斥锁 `mutex` 是递归的，并且在进入时其递归计数大于一，它在阻塞调用者之前被解锁，并且在该服务返回之前重新获取互斥锁时恢复递归计数。

一旦线程在条件变量上阻塞，就会在条件变量 `cond` 和互斥锁 `mutex` 之间形成动态绑定。如果另一个线程调用该服务时指定 `cond` 作为条件变量但使用了不同于 `mutex` 的互斥锁，该服务会立即返回 `EINVAL` 状态。

对于由 `pthread_create()` 服务创建的 Cobalt 线程，该服务是一个取消点。当这样的线程在调用该服务时被取消，互斥锁 `mutex` 会在调用取消清理处理程序之前重新获取。

参数:

- `cond`: 要等待的条件变量；
- `mutex`: 与 `cond` 关联的互斥锁。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `EPERM`，调用者上下文无效；
  - `EINVAL`，指定的条件变量或互斥锁无效；
  - `EPERM`，指定的条件变量不是进程共享的，并且不属于当前进程；
  - `EINVAL`，另一个线程当前使用与 `mutex` 不同的互斥锁阻塞在 `cond` 上；
  - `EPERM`，指定的互斥锁不属于调用者。

标签:

- `xthread-only`，`switch-primary`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    #include <errno.h>

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond;
    int ready = 0;

    void* worker(void* arg) {
        int rc;
        pthread_mutex_lock(&mutex);
        while (!ready) {
            printf("Worker: Waiting for signal (with timeout)...\n");
            rc = pthread_cond_wait(&cond, &mutex);
            if (rc != 0) {
                perror("pthread_cond_timedwait");
                pthread_mutex_unlock(&mutex);
                return NULL;
            }
        }
        printf("Worker: Signal received, ready = %d\n", ready);
        pthread_mutex_unlock(&mutex);
        return NULL;
    }

    int main() {
        pthread_t thread;
        int rc;
        pthread_cond_init(&cond, NULL);
        rc = pthread_create(&thread, NULL, worker, NULL);
        if (rc != 0) {
            perror("pthread_create");
            return 1;
        }

        // 主线程睡眠2秒，然后发送信号
        sleep(2);

        pthread_mutex_lock(&mutex);
        ready = 6;
        printf("Main: Sending signal\n");
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);

        pthread_join(thread, NULL);
        pthread_cond_destroy(&cond);
        return 0;
    }

#### pthread_condattr_destroy()

> int pthread_condattr_destroy(pthread_condattr_t *attr)

销毁条件变量属性对象。

该服务销毁条件变量属性对象 `attr`。该对象对于所有条件变量服务变为无效（它们都返回 `EINVAL`），除了 `pthread_condattr_init()`。

参数:

- `attr`: 要销毁的已初始化的条件变量属性对象。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `EINVAL`，条件变量属性对象 `attr` 无效。

标签:

- `thread-unrestricted`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>

    int main() {
        pthread_condattr_t cond_attr;
        pthread_cond_t cond;
        int result;

        // 初始化条件变量属性对象
        result = pthread_condattr_init(&cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_init failed: %s\n", strerror(result));
            return 1;
        }

        // 可以在这里设置条件变量的其他属性
        // 例如，设置为进程间共享
        result = pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_setpshared failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        // 使用属性对象初始化条件变量
        result = pthread_cond_init(&cond, &cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_cond_init failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        printf("条件变量已成功初始化。\n");

        // 使用完毕后，销毁条件变量和属性对象
        pthread_cond_destroy(&cond);
        pthread_condattr_destroy(&cond_attr);

        return 0;
    }

#### pthread_condattr_getclock()

> int pthread_condattr_getclock(const pthread_condattr_t *attr, clockid_t *clk_id)

获取条件变量属性对象中的时钟选择属性。

该服务将条件变量属性对象 `attr` 中 `clock` 属性的值存储在 `clk_id` 指定的地址。

有关此属性对条件变量影响的描述，请参见 `pthread_cond_timedwait()`。返回的时钟 ID 为 `CLOCK_REALTIME` 或 `CLOCK_MONOTONIC`。

参数:

- `attr`: 已初始化的条件变量属性对象。
- `clk_id`: 成功时用于存储 `clock` 属性值的地址。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `EINVAL`，属性对象 `attr` 无效。

标签:

- `thread-unrestricted`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <time.h>

    int main() {
        pthread_condattr_t cond_attr;
        pthread_cond_t cond;
        int result;
        clockid_t clock_id;

        // 初始化条件变量属性对象
        result = pthread_condattr_init(&cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_init failed: %s\n", strerror(result));
            return 1;
        }

        // 设置条件变量使用CLOCK_MONOTONIC时钟
        result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_setclock failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        // 验证时钟属性是否正确设置
        result = pthread_condattr_getclock(&cond_attr, &clock_id);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_getclock failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        if (clock_id == CLOCK_MONOTONIC) {
            printf("条件变量属性已成功设置为使用CLOCK_MONOTONIC时钟。\n");
        } else {
            printf("设置CLOCK_MONOTONIC时钟属性失败。\n");
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        // 使用属性对象初始化条件变量
        result = pthread_cond_init(&cond, &cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_cond_init failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        printf("条件变量已成功初始化，使用CLOCK_MONOTONIC时钟。\n");

        // 使用完毕后，销毁条件变量和属性对象
        pthread_cond_destroy(&cond);
        pthread_condattr_destroy(&cond_attr);

        return 0;
    }

#### pthread_condattr_getpshared()

> int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared)

获取条件变量属性对象中的进程共享属性。

该服务将条件变量属性对象 `attr` 中 `pshared` 属性的值存储在 `pshared` 指定的地址。

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

参数:

- `attr`: 已初始化的条件变量属性对象。
- `pshared`: 成功时用于存储 `pshared` 属性值的地址。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `EINVAL`，`pshared` 地址无效；
  - `EINVAL`，条件变量属性对象 `attr` 无效。

标签:

- `thread-unrestricted`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>

    int main() {
        pthread_condattr_t cond_attr;
        pthread_cond_t cond;
        int result;
        int pshared;

        // 初始化条件变量属性对象
        result = pthread_condattr_init(&cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_init failed: %s\n", strerror(result));
            return 1;
        }

        // 设置条件变量为进程间共享
        result = pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_setpshared failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        // 验证pshared属性是否正确设置
        result = pthread_condattr_getpshared(&cond_attr, &pshared);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_getpshared failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        if (pshared == PTHREAD_PROCESS_SHARED) {
            printf("条件变量属性已成功设置为进程间共享。\n");
        } else {
            printf("设置进程间共享属性失败。\n");
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        // 使用属性对象初始化条件变量
        result = pthread_cond_init(&cond, &cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_cond_init failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        printf("条件变量已成功初始化，可以在进程间共享。\n");

        // 使用完毕后，销毁条件变量和属性对象
        pthread_cond_destroy(&cond);
        pthread_condattr_destroy(&cond_attr);

        return 0;
    }

#### pthread_condattr_init()

> int pthread_condattr_init(pthread_condattr_t *attr)

初始化条件变量属性对象。

该服务使用所有属性的默认值初始化条件变量属性对象 `attr`。默认值为：

- 对于时钟属性，`CLOCK_REALTIME`；
- 对于进程共享属性，`PTHREAD_PROCESS_PRIVATE`。

如果在已初始化的条件变量属性对象上调用此服务，则该属性对象将被重新初始化。

参数:

- `attr`: 要初始化的条件变量属性对象。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `ENOMEM`，条件变量属性对象指针 `attr` 为 `NULL`。

标签:

- `thread-unrestricted`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>

    int main() {
        pthread_condattr_t cond_attr;
        pthread_cond_t cond;
        int result;

        // 初始化条件变量属性对象
        result = pthread_condattr_init(&cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_init failed: %s\n", strerror(result));
            return 1;
        }

        // 可以在这里设置条件变量的其他属性
        // 例如，设置为进程间共享
        result = pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_setpshared failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        // 使用属性对象初始化条件变量
        result = pthread_cond_init(&cond, &cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_cond_init failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        printf("条件变量已成功初始化。\n");

        // 使用完毕后，销毁条件变量和属性对象
        pthread_cond_destroy(&cond);
        pthread_condattr_destroy(&cond_attr);

        return 0;
    }

#### pthread_condattr_setclock()

> int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clk_id)

设置条件变量属性对象的时钟选择属性。

该服务设置条件变量属性对象 `attr` 的时钟属性。

有关此属性对条件变量影响的描述，请参见 `pthread_cond_timedwait()`。

参数:

- `attr`: 已初始化的条件变量属性对象；
- `clk_id`: 时钟属性的值，可以是 `CLOCK_REALTIME` 或 `CLOCK_MONOTONIC`。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `EINVAL`，条件变量属性对象 `attr` 无效；
  - `EINVAL`，`clk_id` 的值对于时钟属性无效。

标签:

- `thread-unrestricted`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <time.h>

    int main() {
        pthread_condattr_t cond_attr;
        pthread_cond_t cond;
        int result;
        clockid_t clock_id;

        // 初始化条件变量属性对象
        result = pthread_condattr_init(&cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_init failed: %s\n", strerror(result));
            return 1;
        }

        // 设置条件变量使用CLOCK_MONOTONIC时钟
        result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_setclock failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        // 验证时钟属性是否正确设置
        result = pthread_condattr_getclock(&cond_attr, &clock_id);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_getclock failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        if (clock_id == CLOCK_MONOTONIC) {
            printf("条件变量属性已成功设置为使用CLOCK_MONOTONIC时钟。\n");
        } else {
            printf("设置CLOCK_MONOTONIC时钟属性失败。\n");
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        // 使用属性对象初始化条件变量
        result = pthread_cond_init(&cond, &cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_cond_init failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        printf("条件变量已成功初始化，使用CLOCK_MONOTONIC时钟。\n");

        // 使用完毕后，销毁条件变量和属性对象
        pthread_cond_destroy(&cond);
        pthread_condattr_destroy(&cond_attr);

        return 0;
    }

#### pthread_condattr_setpshared()

> int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared)

设置条件变量属性对象的进程共享属性。

该服务设置条件变量属性对象 `attr` 的 `pshared` 属性。

参数:

- `attr`: 已初始化的条件变量属性对象。
- `pshared`: `pshared` 属性的值，可以是以下之一：
  - `PTHREAD_PROCESS_PRIVATE`，表示使用属性对象 `attr` 创建的条件变量仅可被初始化该条件变量的线程所在的同一进程内的线程访问；
  - `PTHREAD_PROCESS_SHARED`，表示使用属性对象 `attr` 创建的条件变量可被任何有权访问该条件变量所在内存的线程访问。

返回值:

- 成功时返回 0；
- 如果出现错误，返回错误号：
  - `EINVAL`，条件变量属性对象 `attr` 无效；
  - `EINVAL`，`pshared` 的值无效。

标签:

- `thread-unrestricted`

示例代码

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>

    int main() {
        pthread_condattr_t cond_attr;
        pthread_cond_t cond;
        int result;
        int pshared;

        // 初始化条件变量属性对象
        result = pthread_condattr_init(&cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_init failed: %s\n", strerror(result));
            return 1;
        }

        // 设置条件变量为进程间共享
        result = pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_setpshared failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        // 验证pshared属性是否正确设置
        result = pthread_condattr_getpshared(&cond_attr, &pshared);
        if (result != 0) {
            fprintf(stderr, "pthread_condattr_getpshared failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        if (pshared == PTHREAD_PROCESS_SHARED) {
            printf("条件变量属性已成功设置为进程间共享。\n");
        } else {
            printf("设置进程间共享属性失败。\n");
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        // 使用属性对象初始化条件变量
        result = pthread_cond_init(&cond, &cond_attr);
        if (result != 0) {
            fprintf(stderr, "pthread_cond_init failed: %s\n", strerror(result));
            pthread_condattr_destroy(&cond_attr);
            return 1;
        }

        printf("条件变量已成功初始化，可以在进程间共享。\n");

        // 使用完毕后，销毁条件变量和属性对象
        pthread_cond_destroy(&cond);
        pthread_condattr_destroy(&cond_attr);

        return 0;
    }