int pthread_cond_timedwait(pthread_cond_t *cond,
pthread_mutex_t *mutex, const struct timespec *abstime);
成功返回0,否则返回一个错误号表示错误信息。
Linux System Error 描述链接
根据上面信息可以清晰知道,pthread_cond_timedwait 函数调用返回 EINVAL。
从 pthread_cond_timedwait 函数原型我们可以得知,有三个入口参数:
在使用 pthread_cond_timedwait 函数时,必须有三步:
项目调用代码如下:
#define HI_COND_TIMEDWAIT_WITH_RETURN(cond, mutex, usec, ret) \
do { \
struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; \
(HI_VOID)clock_gettime(CLOCK_MONOTONIC, &ts); \
ts.tv_sec += (usec / 1000000LL); \
ts.tv_nsec += (usec * 1000LL % 1000000000LL); \
ret = pthread_cond_timedwait(&cond, &mutex, &ts); \
} while (0)
通过对项目代码的分析, 条件变量 cond, 互斥锁 mutex 的使用都符合调用规范,因此猜测传参错误发生在参数 abstime, 而从网上查询信息发现有网友提出 ts.tv_nsec 的值是有限制的,必须小于1s(也就是值不能大于1000000000),参考网友修改对项目代码进行了修改。
(PS:关于ts.tv_nsec 值的限制没有找到相关文档说明,此处依然带着疑问,希望后续可以找到)
修改后代码
#define HI_COND_TIMEDWAIT_WITH_RETURN(cond, mutex, usec, ret) \
do { \
struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; \
(HI_VOID)clock_gettime(CLOCK_MONOTONIC, &ts); \
ts.tv_sec += (usec / 1000000LL); \
ts.tv_nsec += (usec * 1000LL % 1000000000LL); \
if (ts.tv_nsec > 1000000000) { \
ts.tv_sec += 1; \
ts.tv_nsec -= 1000000000; \
} \
ret = pthread_cond_timedwait(&cond, &mutex, &ts); \
} while (0)
sleep | 线程等待,等待期间线程无法唤醒 |
---|---|
pthread_cond_wait | 线程等待信号触发,如果没有信号触发,无限期等待下去。 |
pthread_cond_timedwait | 线程等待一定的时间,如果超时或有信号触发,线程唤醒。 |
关于 pthread_cond_timedwait 函数返回 EINVAL 的信息,在项目期间在调试信息中就已经发现了,但由于当时机器简单运行无异常和本人的侥幸心理,没引起重视,没深究错误原因,以至于到产品测试阶段进行长时间运行时出现了异常停止问题,因此为了告诫自己,写下了此文!
细节决定成败!
致广大而尽精微,极高明而道中庸。