pthread_cond_timedwait()EINVAL的根本原因

Jon*_*ump 4 pthreads

我在非常罕见的情况下看到pthread_cond_timedwait()返回EINVAL并导致系统崩溃.我知道这意味着传入的参数之一必须是无效的,但互斥锁或cond变量如何变为无效?

有没有办法在调用pthread_cond_timedwait()之前检查这些参数以防止崩溃?

Tan*_*ury 10

它没有被指定为exaclty什么构成无效,但这里有一些我观察到的pthread_cond_timedwait返回原因EINVAL:

  • 条件和/或互斥锁未正确初始化.检查初始化返回结果,并验证是否显式链接了正确的pthread库.当链接各种版本的glibc时可能会出现偶发问题,导致难以调试init调用返回成功的情况,但是对象未正确初始化.
  • 任何未定义的行为都可能导致无效的内部状态,pthread调用可能会或可能不会检测到这种状态.未定义的行为可能来自:
    • 在不破坏互斥锁或条件变量的情况下多次初始化互斥锁或条件变量.
    • 在销毁之后但在重新初始化之前使用互斥锁或条件变量.
    • 条件和/或互斥锁由应用程序代码手动写入.
    • 当线程在对象上等待时,互斥锁或条件变量被销毁.
  • 不同的互斥锁使用相同的条件变量.
  • 绝对时间参数具有大于10亿小于0或更大的值tv_nsec.

如果没有手动模仿pthread正在进行的验证调用,那么我不知道在调用之前检查参数的方法pthread_cond_timewait().但是,pthread_cond_timewait()返回EINVAL不应该导致致命的崩溃,因为它是一个特定的情况.考虑检查可能无法正确处理返回结果的其他应用程序代码区域.例如,只要返回不成功,代码就会成功ETIMEDOUT.

  • `abstime参数的tv_nsec值小于0或大于1,000,000,000.可能是最常见的错误,我猜 (3认同)

小智 5

我想分享我在这个问题上的经验,时间值是'timespec',它的'tv_nsec'范围应该保持在[0, 999999999]内,因此如果你设置nano值超过1秒,一些linux可能会返回 EINVAL!

struct timespec {
    time_t tv_sec;      /* Seconds */
    long   tv_nsec;     /* Nanoseconds [0 .. 999999999] */ 
};
Run Code Online (Sandbox Code Playgroud)

希望这能帮助你摆脱困境。