【问题标题】:Can you help explain how this buffer logic works你能帮忙解释一下这个缓冲区逻辑是如何工作的吗
【发布时间】:2017-01-24 06:42:48
【问题描述】:

我正在尝试使用 inotify 做一些工作并更好地理解 C。我很新手。我正在查看 inotify 手册页,并看到了一个使用 inotify 的示例。我对他们如何使用缓冲区有一些疑问。代码在这里:

http://man7.org/linux/man-pages/man7/inotify.7.html

我最感兴趣的块是:

       char buf[4096]
           __attribute__ ((aligned(__alignof__(struct inotify_event))));
       const struct inotify_event *event;
       int i;
       ssize_t len;
       char *ptr;

       /* Loop while events can be read from inotify file descriptor. */

       for (;;) {

           /* Read some events. */

           len = read(fd, buf, sizeof buf);
           if (len == -1 && errno != EAGAIN) {
               perror("read");
               exit(EXIT_FAILURE);
           }

           /* If the nonblocking read() found no events to read, then
              it returns -1 with errno set to EAGAIN. In that case,
              we exit the loop. */

           if (len <= 0)
               break;

           /* Loop over all events in the buffer */

           for (ptr = buf; ptr < buf + len;
                   ptr += sizeof(struct inotify_event) + event->len) {

               event = (const struct inotify_event *) ptr;

我想了解的是如何准确处理此缓冲区中的位。这是我所知道的:

我们定义了一个 4096 的char buf,这意味着我们有一个大约 4kbs 大小的缓冲区。当调用 read(fd, buf, sizeof buf)len 时,将是 0 - 4096 之间的任何位置(可能发生部分读取)。

我们做了一些异步检查,这很明显。

现在我们进入 for 循环,这里是我有点困惑的地方。我们将ptr 设置为等于buf,然后将ptr 的大小与buff + len 进行比较。

此时ptr 是否等于值 '4096' ?如果是这样,我们会说;是 ptr:4096

然后我们作为迭代器表达式,增加ptr+= inotify 事件的大小。

我习惯了更高级别的 OOP 语言,我会在其中声明一个“inotify_event”对象的缓冲区。但是我假设因为我们只是从“读取”中取回一个字节数组,所以我们需要在“inotify_event”边界处提取字节并将这些位类型转换为事件对象。这听起来正确吗?

此外,我也不确定如何使用 buf[4096] 值进行比较。我们没有检查数组当前大小(分配的索引)的概念,所以我假设在比较使用时,在这种情况下我们正在比较它分配的内存空间“4096”的大小?

感谢您的帮助,这是我第一次真正地处理缓冲区中的位。试图把我的头包裹在这一切上。任何进一步的阅读都会有所帮助!我一直在寻找大量关于 C 作为语言的阅读,大量关于 Linux 系统编程的阅读,但我似乎找不到诸如“使用缓冲区”或两者之间的灰色区域之类的主题。

【问题讨论】:

    标签: c buffer inotify


    【解决方案1】:

    当您在 C 中进行赋值 ptr = buf 时,您正在将 buf 的第一个元素的地址分配给 ptr。因此,比较是检查 ptr 是否超出缓冲区的末尾。

    循环跳过一个struct inotify_event(定义为here)所需的字节数,以及事件名称的长度。

    【讨论】:

      【解决方案2】:
      ptr = buf
      

      您正在将buf(即&amp;buf[0])的第一个元素的地址分配给指针ptr。因此,您开始使用从第一个元素开始的指针循环遍历 buf。

      ptr < buf + len;
      

      这是检查您的ptr 指针是否在数组中“移动”直到buf 结束。它是使用指针算术制作的。所以循环比较ptr指向的地址和buf的地址+read函数返回的缓冲区的len

      ptr += sizeof(struct inotify_event) + event->len
      

      最后,指针向前移动了事件结构 struct inotify_event 加上事件 len 的大小,我猜它是根据事件类型而变化的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-24
        • 2022-10-13
        • 2021-12-22
        • 2011-02-16
        • 1970-01-01
        • 2013-03-13
        • 1970-01-01
        相关资源
        最近更新 更多