提问人:CoolSteve 提问时间:11/13/2023 更新时间:11/13/2023 访问量:59
在 C 中测量子进程退出所需的时间
Measuring the time a child process takes to exit in C
问:
我正在尝试在 C 中创建一个非常小的单元测试仅标头库。
我有一个非常基本的宏设置,称为分叉进程并执行给定的测试用例,这只是一个函数。我想掩盖测试无法正确退出的情况(例如,使用)。
我想打印出测试用例运行所需的时间,最好以秒为单位。RUN_TEST_CASE
fork
SIGSEGV
这是我目前拥有的代码——
#include <stdio.h>
#include <unistd.h>
#include <wait.h>
#include <sys/types.h>
#include <time.h>
#define __MINTEST_SAFE_BLOCK(block) \
do \
{ \
block \
} while (0)
#define TEST_CASE(test) static void test(void)
#define TEST_SUITE(suite) static void suite(void)
#define __RUN_TEST_CASE(test, caller) __MINTEST_SAFE_BLOCK( \
pid_t pid; \
int status; \
clock_t begin; \
clock_t end; \
double time_spent; \
\
begin = clock(); \
pid = fork(); \
switch (pid) { \
case -1: \
perror("fork"); \
break; \
case 0: \
test(); \
break; \
default: \
waitpid(pid, &status, 0); \
end = clock(); \
time_spent = (end - begin); \
if (WIFEXITED(status)) \
{ \
printf("%s:%s passed after %fms [%d]\n", caller, #test, time_spent, WEXITSTATUS(status)); \
} \
else if (WIFSIGNALED(status)) \
{ \
printf("%s:%s failed after %fms [%d]\n", caller, #test, time_spent, WTERMSIG(status)); \
} \
break; \
})
#define RUN_TEST_CASE(test) __RUN_TEST_CASE(test, __func__)
#define RUN_TEST_SUITE(suite) suite()
我正在使用以下 C 代码测试这些宏 -
#include "mintest.h"
TEST_CASE(test_something) {
printf("In test\n");
sleep(2);
*(volatile int*)NULL;
};
TEST_SUITE(test_suite) {
RUN_TEST_CASE(test_something);
};
int main(void) {
RUN_TEST_SUITE(test_suite);
return 0;
}
我希望看到打印出来的测试失败并花了大约 2 秒钟,但我得到的结果非常不一致 -
In test
test_suite:test_something failed after 574.000000ms [11]
In test
test_suite:test_something failed after 462.000000ms [11]
In test
test_suite:test_something failed after 689.000000ms [11]
我做错了什么吗?也许我对什么有错误的理解?waitpid()
答:
3赞
Chris Dodd
11/13/2023
#1
clock()
返回处理器时间(不是经过时间),以时钟周期为单位,而不是毫秒。您需要除以才能转换为秒,但这可能仍然不是您想要的,因为它只是在父项中花费的时间,不包括在 中花费的任何时间。(double)CLOCKS_PER_SEC
wait
您可以使用代替来获得更有用的数字。clock_gettime
在子项中运行测试后,应调用 (或 );否则,它可能会继续运行测试代码(这意味着它将在孙子项中运行后续测试的额外副本,并且通常会爆炸。在您的特定情况下,它不会发生,因为测试用例在 SEGV 中失败,但其他通过的测试可能会出现此问题。exit
_exit
评论
sleep()
)clock(3)
clock_gettime(CLOCK_MONOTONIC,...)
begin = ...
waitpid
fork
clock
clock*
msgsnd/msgrcv