memcpy() 是休眠函数吗?

Is memcpy() a sleeping function?

我想在不使用 for 循环的情况下复制数组的内容。拥有自旋锁时进行复制。

memcpy() 有没有可能休眠?

memcpy(或任何一般的内存访问)可能发生的事情:

  • 如果部分源或目标是不可访问(无效)内存,memcpy 可能会使您的进程崩溃,这可能会使共享自旋锁处于错误状态。
  • 如果需要调入部分源内存,memcpy 可以在内核为您获取内存时阻塞。
  • 如果源或目标的一部分内存映射到 I/O,memcpy 可能会在内核执行 I/O 时阻塞。 (在极端情况下,如内存映射网络文件,memcpy 可能会无限期阻塞)。

内核也可以在复制过程中的任何时候自由交换您的进程,这意味着复制可能需要任意长的时间才能真正完成。

但是,memcpy 不会执行常规内存访问不会执行的任何操作。因此,将它与自旋锁一起使用应该是安全的(无论如何,与正常访问内存一样安全)。

我发现你的问题有些不一致。我自己解释一下。

自旋锁或者一般的忙锁,维护等待获取锁的进程(或线程)而不释放cpu给另一个进程(或线程)这意味着非常快释放锁时解锁和重新安排机制,但是等待时间长的模型非常昂贵...

曾经说过....如果你正在使用自旋锁,原因一定是进程或线程用来检查锁何时被释放的循环不应该执行超过三四次,或者如果锁已被释放,cpu 将被浪费,只是一次又一次地检查一次。

这完全不鼓励像您要求的那样进行阻塞操作(内存副本通常很奇怪,它必须处理不存在的资源 --- 内存页 ---,但是当它处理时,您的自旋锁将进入数百万支票的循环)

自旋锁旨在保护非常小的内存块,其中访问最多可以表示对内存的两次或三次访问。在这种情况下,自旋锁将解决问题,因为使用自旋锁让线程等待并重新安排它比 wait/awake 进程快百万倍。但这与 memcpy(3) 函数的使用明显相反,因为它是一个通用的复制函数,允许一次性进行大内存复制。这意味着资源为一个线程锁定的时间,可以表示对另一个线程的数百万次检查(在不同的核心中,因为这是使用自旋锁的另一个原因,当你有一个不同的核心要等待两三个访问锁以查看它已解锁)

在我看来,自旋锁的唯一用途是保护信号量的计数器,或保护对 cond 变量或互斥锁的访问,但绝不能用作一般内存复制或大型资源保护.在这些情况下,最好使用普通的睡眠锁。如果您打算使用 memcpy(3),我唯一可以假设的是,您使用锁来保护大量内存,同时将它们复制到...。使用 sempahore 或 mutex 是更好的处理程序。

在现代内核中,进程的唤醒效率如此之高,以至于用户模式自旋锁几乎完全无法使用。

作为结论,我的猜测是您不必考虑使用 memcpy() 来保护共享内存区域......但要考虑使用自旋锁本身来进行保护。在大多数情况下,这将是资源的损失,并且会使您的系统变得更重、更慢。