2828

14 分钟

#C 语言标准库函数 mtx_timedlock

/********************************************* * @brief 锁定互斥量,支持超时 * @param mutex 要加锁的互斥量 ID * @param time_point 超时的时间点 * @return 是否成功 ********************************************/ int mtx_timedlock(mtx_t* mutex, const struct timespec* restrict time_point);

说明

阻塞当前线程,直到锁定互斥量或超时。

超时时间 time_point 是基于 TIME_UTC 的绝对时间点,而非持续时间。

对于持续时间,需要换算成绝对时间点,例如:

/********************************************* * @brief 生成超时的绝对时间点 * @param[out] time_point 返回绝对时间点 * @param sec 持续的秒数 ********************************************/ void generate_timeout(struct timespec* time_point, int sec) { timespec_get(time_point, TIME_UTC); // 获取基于 TIME_UTC 的当前时间 time_point->tv_sec += sec; // 增加 sec 秒 }

如果互斥量不支持超时,则此操作的行为未定义。

对于非递归的互斥量,如果已经被当前线程锁定,则此操作的行为未定义。

参数

  • mutex - 要加锁的互斥量 ID
  • time_point - 超时的时间点

返回值

  • 成功时返回 thrd_success
  • 失败时返回 thrd_error

#示例

#include <stdio.h> #include <threads.h> #include <time.h> // 线程函数 int func(void* data) { mtx_t* mutex = (mtx_t*)data; // 通过参数传递互斥量 // 计算绝对时间点 struct timespec time_point; timespec_get(&time_point, TIME_UTC); // 获取基于 TIME_UTC 的当前时间 time_point.tv_sec += 5; // 增加 5 秒 printf("开始时间: %s", ctime(&(time_t){time(NULL)})); // 加锁 if (mtx_timedlock(mutex, &time_point) == thrd_success) { printf("加锁成功\n"); } else { printf("加锁失败,超时\n"); } printf("结束时间: %s", ctime(&(time_t){time(NULL)})); return 0; } int main(void) { // 创建支持超时的互斥量 mtx_t mutex; mtx_init(&mutex, mtx_timed); // 加锁 mtx_lock(&mutex); // 创建线程 thrd_t th; thrd_create(&th, func, &mutex); // 通过参数传递数据和互斥量 // 等待线程结束 thrd_join(th, NULL); // 加锁 mtx_unlock(&mutex); // 清除互斥量 mtx_destroy(&mutex); return 0; }

运行结果

开始时间: Sun Aug 24 13:54:46 2025 加锁失败,超时 结束时间: Sun Aug 24 13:54:51 2025

说明

示例中,子线程函数调用 mtx_timedlock 进行超时加锁,超时的时间点是当前时间加 5 秒,也就是 5 秒后超时。

主线程在创建子线程前已经对互斥量加锁,并且始终没有解锁,因此子线程无法成功加锁,只能在 5 秒后返回失败。

#推荐阅读

#参考标准

  • C17 standard (ISO/IEC 9899:2018):
    • 7.26.4.4 The mtx_timedlock function (p: 278)
  • C11 standard (ISO/IEC 9899:2011):
    • 7.26.4.4 The mtx_timedlock function (p: 381-382)

创建于 2025/8/24

更新于 2025/8/24