我有一个简单的看门狗机制,如下所示:
time_t timer = time(NULL);
int n = 0;
while (true) {
if (time(NULL) >= timer + 10) {
timer = time(NULL);
char szData[64];
memset(szData, 0, 64);
sprintf(szData, "s|%d|%s", tid, function_name);
if ((n = strlen(szData)) > 0) {
int t = 0;
int fp = 0;
while ((fp = open("/proc/counters", O_WRONLY | O_EXCL)) == -1 && errno == EACCESS) {
if (++t > 4) {
break;
}
usleep(260000);
}
if (fp == -1) {
return 1;
}
write(fp, szData, n);
close(fp);
}
}
}
在这种情况下,每个计数器应该达到最大值 10,但我的问题是,有时,其中一些计数器达到最大值 20,然后是 30,依此类推。在内核模块方面,我发现重置命令确实没有及时到达,并且在下一轮中,它在一秒钟内收到两个命令,就像第一个命令被延迟一样。示例:
/proc 计数器文件的内容
*856 7 20/600 thread_function_name
内核模块的调试打印
8 月 26 日 11:16:38 XWEB-PRO kern.info 内核:[114.086453] 注册 856
8 月 26 日 11:16:38 XWEB-PRO kern.info 内核:[ 124.138523] 注册 856
8 月 26 日 11:16:58 XWEB-PRO kern.info 内核:[ 134.190508] 注册 856
8 月 26 日 11:16:58 XWEB-PRO kern.info 内核:[ 144.242274] 注册 856
8 月 26 日 11:16:58 XWEB-PRO kern.info 内核:[ 144.242277] 注册 856
8 月 26 日 11:17:08 XWEB-PRO kern.info 内核:[ 154.294433] 注册 856
8 月 26 日 11:17:28 XWEB-PRO kern.info 内核:[ 164.346516] 注册 856
8 月 26 日 11:17:28 XWEB-PRO kern.info 内核:[ 174.398552] 注册 856
8 月 26 日 11:17:38 XWEB-PRO kern.info 内核:[ 184.468022] 注册 856
8 月 26 日 11:17:48 XWEB-PRO kern.info 内核:[ 194.522241] 注册 856
如你所见,我错过了 11:16:48 的命令,但我在 11:16:58 有 3 个命令。然后我错过了 11:17:18 的那一场,但在 11:17:28 得到了 2 场。 我已经尝试过 fflush、fsync 和sync,但没有成功。有人能指出我正确的方向吗?谢谢你
终于发现问题了。看起来这是一个竞争条件问题。有 10 个线程同时写入 /proc 文件,因此内核模块可能会错过某些写入操作(实际上重置总是以 10 秒的倍数发生)。我在互斥条件下包围了用户空间中的打开/写入/关闭序列,问题似乎消失了。