调用clock_settime设置进程CPU时钟报EINVAL错误,是否需要特殊权限?
问题根因
- 你遇到的
EINVAL错误和代码逻辑、运行权限都无关,核心原因是CLOCK_PROCESS_CPUTIME_ID属于内核维护的只读时钟,不支持clock_settime修改操作。 - 该时钟的作用是统计进程从启动到当前时刻消耗的CPU总时间,设计上就不允许用户态手动修改取值,所有调用
clock_settime修改该时钟的操作都会直接返回EINVAL。
错误码区分规则
你可以通过返回的错误码快速定位问题类型:
EINVAL:参数非法,常见触发场景为使用了不支持设置的时钟ID、struct timespec参数取值非法(比如tv_nsec超过1000000000)EPERM:权限不足,仅当你操作的是可设置时钟(比如CLOCK_REALTIME)、且当前进程没有CAP_SYS_TIME权限时才会触发。
现有代码小优化
你代码中打印timespec成员的格式符存在兼容性问题:tv_sec是time_t类型、tv_nsec是long类型,在64位系统下均为8字节长度,使用%d(对应4字节整型)会导致输出异常,建议修改为%ld格式符。
替代实现建议
如果你是想要统计某段代码的CPU耗时,不需要重置时钟,直接在目标代码段前后分别调用clock_gettime获取时间、计算差值即可,示例逻辑如下:
struct timespec start, end; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); // 此处写入待统计耗时的代码 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); // 耗时计算:(end.tv_sec - start.tv_sec) * 1000000000 + (end.tv_nsec - start.tv_nsec),单位为纳秒
内容的提问来源于stack exchange,提问作者Shubham Johri
相关产品推荐
相关产品推荐

