【问题标题】:ptmalloc_lock_all weird for loopptmalloc_lock_all 奇怪的 for 循环
【发布时间】:2019-08-05 23:03:08
【问题描述】:

我正在尝试理解 glibc 中的一些代码。为什么要使用这个奇怪的 for 循环?我猜出于某种原因编译器优化?

 237   for (ar_ptr = &main_arena;; )
 238     { 
 239       (void) mutex_lock (&ar_ptr->mutex);
 240       ar_ptr = ar_ptr->next;
 241       if (ar_ptr == &main_arena)
 242         break;
 243     }

【问题讨论】:

  • do {} while()的方式看起来很奇怪
  • 这似乎是Wolfram Gloger's代码中的常用成语。

标签: c memory heap-memory


【解决方案1】:

你觉得那个循环中有什么奇怪的地方?

显然,main_arena 是循环链表的头部。要遍历一个循环列表,请跟随下一个链接,直到您发现自己回到了起点。但是您必须在循环结束时进行该测试,因为退出条件在第一次迭代时为真。

循环链表很常见,尤其是双向链表。使列表循环避免了许多插入和删除操作的特殊情况检查。

在这种情况下,每个列表项中都有一个互斥锁,循环的重点是锁定所有互斥锁。这可能就是该函数被称为lock_all 的原因。

您可以使用 do ... while 编写经过结束测试的循环,但该构造无法初始化循环变量。

【讨论】:

  • 我的脑残,我意识到它显然是在遍历一个循环,哈哈,它只是不常见的链表被使用。我尝试启动一些线程,除非我们并行讨论线程,否则它们最终都使用相同的堆 main_arena。有没有你能想到的使用多个的例子?
  • 我并没有真正了解代码,但我的理解是,如果线程需要独占访问某个 arena 并且找不到一个未锁定。由于每个线程都有一小部分可用的专有内存块缓存,因此并非每个分配请求都需要一个 arena,但是如果您在多个线程中同时进行了一堆不同大小的分配,您可能会看到更多的 arena。当然,您需要让线程并行执行。否则,他们不会互相竞争。
  • @k3170makan:另外,我不知道为什么(或者即使)它使用双向链表。您必须阅读代码,而我没有这样做(至少最近没有)。
猜你喜欢
  • 2019-02-11
  • 2019-04-30
  • 2017-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多