在可用内存不足的情况下,pthread_create 失败并出现 ENOMEM

发布于 2024-12-01 05:15:57 字数 964 浏览 2 评论 0原文

我有一块 SH4 板,这是规格...

uname -a
Linux LINUX7109 2.6.23.17_stm23_A18B-HMP_7109-STSDK #1 PREEMPT Fri Aug 6 16:08:19 ART 2010
sh4 unknown

假设我已经吃掉了几乎所有的内存,只剩下 9 MB 了。

free
 total       used       free     shared    buffers     cached
Mem:         48072      42276       5796          0        172       3264
-/+ buffers/cache:      38840       9232
Swap:            0          0          0

现在,当我尝试启动具有默认堆栈大小(8 MB)的单个线程时 pthread_create 失败并显示 ENOMEM。如果我跟踪我的测试代码,我可以看到失败的函数是 mmap:

old_mmap(NULL, 8388608, PROT_READ|PROT_WRITE|PROT_EXEC,                       
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)

但是,当我使用 ulimit -s 将堆栈大小设置为较低值时:

ulimit -s 7500

我现在可以启动 10 个线程。每个线程不分配任何东西,所以它 仅消耗最小的开销(每个线程大约 8 kb,对吧?)。

所以,我的问题是:

知道 mmap 实际上并不消耗内存, 为什么当可用内存低于时 pthread_create() (或 mmap)会失败 线程堆栈大小?

I have a SH4 board, here are the specs...

uname -a
Linux LINUX7109 2.6.23.17_stm23_A18B-HMP_7109-STSDK #1 PREEMPT Fri Aug 6 16:08:19 ART 2010
sh4 unknown

and suppose I have eaten pretty much all the memory, and have only 9 MB left.

free
 total       used       free     shared    buffers     cached
Mem:         48072      42276       5796          0        172       3264
-/+ buffers/cache:      38840       9232
Swap:            0          0          0

Now, when I try to launch a single thread with default stack size (8 MB)
the pthread_create fails with ENOMEM. If I strace my test code, I can see that the function that is failing is mmap:

old_mmap(NULL, 8388608, PROT_READ|PROT_WRITE|PROT_EXEC,                       
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)

However, when I set the stack size to a lower value using ulimit -s:

ulimit -s 7500

I can now launch 10 threads. Each thread does not allocate anything, so it
is only consuming the minimum overhead (aprox. 8 kb per thread, right?).

So, my question is:

Knowing that mmap doesnt actually consume the memory,
Why is pthread_create() (or mmap) failing when memory available is below
the thread stack size ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

愿与i 2024-12-08 05:15:57

VM 设置 /proc/sys/vm/overcommit_memory (又名 sysctl vm.overcommit_memory)控制 Linux 是否愿意分配比 RAM+swap 组合更多的地址空间机器的。 (当然,如果您实际上尝试访问那么多内存,某些东西将会崩溃。尝试搜索“linux oom-killer”...)

此设置的默认值是 0。我将推测有人将其设置为您系统上的其他内容。

The VM setting /proc/sys/vm/overcommit_memory (aka. sysctl vm.overcommit_memory) controls whether Linux is willing to hand out more address space than the combined RAM+swap of the machine. (Of course, if you actually try to access that much memory, something will crash. Try a search on "linux oom-killer"...)

The default for this setting is 0. I am going to speculate that someone set it to something else on your system.

帅的被狗咬 2024-12-08 05:15:57

在 glibc 下,线程的默认堆栈大小为 2-10 兆字节(通常为 8)。您应该使用 pthread_attr_setstacksize 并使用生成的属性对象调用 pthread_create 来请求具有较小堆栈的线程。

Under glibc, the default stack size for threads is 2-10 megabytes (often 8). You should use pthread_attr_setstacksize and call pthread_create with the resulting attributes object to request a thread with a smaller stack.

两仪 2024-12-08 05:15:57

mmap 消耗地址空间

指针必须唯一标识内存中的一块“内存”(包括mmap文件)。

32位指针只能寻址2/3GB内存(32位=2^32=4GB。但是内核保留了一些地址空间)。这个地址空间是有限的。

进程中的所有线程共享相同的地址空间,但不同的进程有单独的地址空间。

mmap consume address space.

Pointers have to uniquely identify a piece of "memory" (including mmap file) in memory.

32-bit pointer can only address 2/3GB memory (32bit = 2^32 = 4GB. But some address space is reserved by kernel). This address space is limited.

All threads in the process share the same address space, but different process have separate address spaces.

℡寂寞咖啡 2024-12-08 05:15:57

这是操作系统优雅地失败操作的唯一机会。如果实现允许此操作成功,则在无法返回失败代码的操作(例如堆栈增长)期间可能会耗尽内存。操作系统宁愿让操作优雅地失败,也不愿冒着杀死完全无辜的进程的风险。

This is the operating system's only chance to fail the operation gracefully. If the implementation allows this operation to succeed, it could run out of memory during an operation that it cannot return a failure code for, such as the stack growing. The operating system prefers to let an operation fail gracefully than risk having to kill a completely innocent process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文