在常规磁盘文件上使用 select 之类的函数
Use select like function on regular disk file
我有一台计算机将一些传感器数据记录到 8 个不同的文件中。
我开发了一个软件,当你使用rj45数据线连接两台机器时,可以将这些数据复制到另一台电脑上。
在我的计算机上检索数据后,我需要使用伪串行(使用 socat)逐行发送每个文件。
我创建了一个使用嵌套 for 循环的程序来检查所有 8 个文件中的数据是否准备就绪,然后提取一行并将其发送到 puttySX。
问题是 CPU 用法。减少它的一种方法是使用阻塞函数来了解数据是否已准备好读取,但是套接字或串行端口上是否有类似 select 的函数,但对于此类文件?
如果没有,我该怎么办?谢谢
您可以查看 inotify,它可以让您监控文件系统事件。
这是一个让您入门的示例代码(这不是生产代码):
#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#define BUF_LEN (sizeof(struct inotify_event) * 1)
int main(int argc, char *argv[])
{
char *filepath;
int fd, wd;
struct inotify_event *event;
char buf[BUF_LEN];
ssize_t ret;
if (argc != 2)
{
fprintf(stderr, "Usage: ./%s <filepath>\n", argv[0]);
return (EXIT_FAILURE);
}
filepath = argv[1];
/* Initialization */
fd = inotify_init();
if (fd == -1)
{
perror("inotify_init()");
return (EXIT_FAILURE);
}
/* Specify which file to monitor */
wd = inotify_add_watch(fd, filepath, IN_MODIFY);
if (wd == -1)
{
perror("inotify_add_watch");
close(fd);
return (EXIT_FAILURE);
}
/* Wait for that file to be modified, */
/* and print a notification each time it does */
for (;;)
{
ret = read(fd, buf, BUF_LEN);
if (ret < 1)
{
perror("read()");
close(fd);
return (EXIT_FAILURE);
}
event = (struct inotify_event *)buf;
if (event->mask & IN_MODIFY)
printf("File modified!\n");
}
close(fd);
return(EXIT_SUCCESS);
}
所以,
我post回答我的问题。感谢@yoones,我找到了一些技巧来做到这一点。
创建日志文件时,我在如下所示的 ini 文件中将 bool 设置为 true
[CreatedFiles]
cli1=false
cli2=false
cli3=false
cli4=false
cli5=false
cli6=false
cli7=false
cli8=false
另一个程序使用inotify 来检测相应文件中的创建和修改。一旦有一些变化,它就会读取 ini 文件,处理数据,当它完成读取数据时,它会删除日志文件,并在相应行的 ini 文件中写入 false。
由于我必须同时处理多个日志文件,所以每次读取一行时,我都会验证我的 ini 文件,看看我是否也必须开始处理另一个日志文件,这样我就可以启动多个进程同时。
我做了一个无限的 while 循环,所以当所有进程都完成后,程序返回到 select 调用,等待一些变化而不消耗所有 CPU 的资源。
对不起,如果我不是很清楚,英语不是我的母语。
感谢大家的回复和评论。
我有一台计算机将一些传感器数据记录到 8 个不同的文件中。 我开发了一个软件,当你使用rj45数据线连接两台机器时,可以将这些数据复制到另一台电脑上。
在我的计算机上检索数据后,我需要使用伪串行(使用 socat)逐行发送每个文件。
我创建了一个使用嵌套 for 循环的程序来检查所有 8 个文件中的数据是否准备就绪,然后提取一行并将其发送到 puttySX。
问题是 CPU 用法。减少它的一种方法是使用阻塞函数来了解数据是否已准备好读取,但是套接字或串行端口上是否有类似 select 的函数,但对于此类文件?
如果没有,我该怎么办?谢谢
您可以查看 inotify,它可以让您监控文件系统事件。
这是一个让您入门的示例代码(这不是生产代码):
#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#define BUF_LEN (sizeof(struct inotify_event) * 1)
int main(int argc, char *argv[])
{
char *filepath;
int fd, wd;
struct inotify_event *event;
char buf[BUF_LEN];
ssize_t ret;
if (argc != 2)
{
fprintf(stderr, "Usage: ./%s <filepath>\n", argv[0]);
return (EXIT_FAILURE);
}
filepath = argv[1];
/* Initialization */
fd = inotify_init();
if (fd == -1)
{
perror("inotify_init()");
return (EXIT_FAILURE);
}
/* Specify which file to monitor */
wd = inotify_add_watch(fd, filepath, IN_MODIFY);
if (wd == -1)
{
perror("inotify_add_watch");
close(fd);
return (EXIT_FAILURE);
}
/* Wait for that file to be modified, */
/* and print a notification each time it does */
for (;;)
{
ret = read(fd, buf, BUF_LEN);
if (ret < 1)
{
perror("read()");
close(fd);
return (EXIT_FAILURE);
}
event = (struct inotify_event *)buf;
if (event->mask & IN_MODIFY)
printf("File modified!\n");
}
close(fd);
return(EXIT_SUCCESS);
}
所以,
我post回答我的问题。感谢@yoones,我找到了一些技巧来做到这一点。
创建日志文件时,我在如下所示的 ini 文件中将 bool 设置为 true
[CreatedFiles]
cli1=false
cli2=false
cli3=false
cli4=false
cli5=false
cli6=false
cli7=false
cli8=false
另一个程序使用inotify 来检测相应文件中的创建和修改。一旦有一些变化,它就会读取 ini 文件,处理数据,当它完成读取数据时,它会删除日志文件,并在相应行的 ini 文件中写入 false。
由于我必须同时处理多个日志文件,所以每次读取一行时,我都会验证我的 ini 文件,看看我是否也必须开始处理另一个日志文件,这样我就可以启动多个进程同时。
我做了一个无限的 while 循环,所以当所有进程都完成后,程序返回到 select 调用,等待一些变化而不消耗所有 CPU 的资源。
对不起,如果我不是很清楚,英语不是我的母语。
感谢大家的回复和评论。