当前位置: 首页 > 面试题库 >

取消共享--pid / bin / bash-fork无法分配内存

方承弼
2023-03-14
问题内容

我正在尝试使用linux名称空间。特别是pid名称空间。

我以为我可以用bash测试一下,但是遇到了这个问题:

unshare -p /bin/bash
bash: fork: Cannot allocate memory

从那里运行ls进行了核心转储。退出是唯一的可能。

为什么这样做呢?


问题答案:

该错误是由PID 1进程在新名称空间中退出引起的。

在bash开始运行之后,bash将派生几个新的子流程来执行某些操作。如果在不使用-
f的情况下运行取消共享,则bash将具有与当前“取消共享”进程相同的pid。当前的“取消共享”进程调用取消共享系统调用,创建新的pid名称空间,但是当前的“取消共享”进程不在新的pid名称空间中。这是linux内核的预期行为:进程A创建一个新的名称空间,进程A本身不会放入新的名称空间,只有进程A的子进程将被放入新的名称空间。因此,当您运行时:

取消共享-p / bin / bash

取消共享进程将执行/ bin / bash,并且/ bin / bash派生几个子进程,bash的第一个子进程将成为新名称空间的PID
1,并且该子进程将在完成其工作后退出。因此,新名称空间的PID 1退出。

PID 1进程具有特殊功能:它应该成为所有孤立进程的父进程。如果根名称空间中的PID 1进程退出,内核将出现恐慌。如果子命名空间中的PID
1进程退出,Linux内核将调用disable_pid_allocation函数,该函数将清除该命名空间中的PIDNS_HASH_ADDING标志。当Linux内核创建新进程时,内核将调用alloc_pid函数在命名空间中分配PID,并且如果未设置PIDNS_HASH_ADDING标志,则alloc_pid函数将返回-
ENOMEM错误。这就是为什么出现“无法分配内存”错误的原因。

您可以使用’-f’选项解决此问题:

取消共享-fp / bin / bash

如果使用’-f’选项运行unshare,unshare将在创建新的pid名称空间后派生一个新进程。然后在新进程中运行/ bin /
bash。新进程将是新pid名称空间的pid 1。然后bash还将派生几个子流程来完成一些工作。由于bash本身是新pid名称空间的pid
1,因此其子进程可以正常退出。



 类似资料:
  • 问题内容: 我试图在共享内存上发布一些随机的东西;出于某些奇怪的原因,阅读器没有选择发件人写的东西 这是发件人: 这是读者: 如果重新启动阅读器,则阅读器确实能够读取发送方已写入的最后一个值。 但是,如果我先启动阅读器,然后再启动发送器,则阅读器不会拾取发送器写入的所有值。 为了使这个更奇怪,如果我在SHM :: read()中取消对printf语句的注释,那么读者有时可以使用。 任何的想法? G

  • 问题内容: 全部:这是我的服务器内存信息,带有“ free -m” 我的Redis服务器已使用46G内存,几乎有15G可用空间 据我所知,fork是写时复制的,当有15G可用内存时,它应该不会失败,这足以分配必要的内核结构。 此外,当redis服务器使用42G内存时,bgsave可以,而fork也可以。 我可以调整任何VM参数以使fork返回成功吗? 问题答案: 从 proc(5) 手册页中: /

  • 共享内存是两个或多个进程共享的内存。 但是,为什么我们需要共享内存或其他通信方式呢? 重申一下,每个进程都有自己的地址空间,如果任何进程想要将自己的地址空间的某些信息与其他进程进行通信,那么只能通过IPC(进程间通信)技术进行。 我们已经知道,通信可以在相关或不相关的进程之间进行。 通常,使用管道或命名管道来执行相互关联的进程通信。 可以使用命名管道或通过共享内存和消息队列的常用IPC技术执行无关

  • 它编译得很好,但是当我试图运行它时,当它到达部分时,我得到了一个分段错误。我在其他地方读到过,不应该创建指向信号量的指针,但是当我没有创建并尝试时,我遇到了一个关于需要lvalue的错误。任何帮助都将不胜感激。

  • 我还在努力把我的头缠在共享的记忆上。我试图完成的是拥有一个豆荚数组。每个pod还将包含一个KeyValue数组。 因此,在这一点上,我在一个pod中有一个keyValue,如果我从同一个文件中读取共享内存,我就没有问题了。 当我试图从另一个进程中读取时,问题就出现了。我有以下文件 printf导致seg错误,我认为它试图访问没有分配任何内容的部分内存,而printf实际上会在我的第一个文件中打印。

  • 我在/usr/local/lib中有libcommon.so,我在程序中链接了这个库。 gcc -o测试test _ Prog . c-L/usr/local/lib-llib common . so 我也试过这个 gcc -o test test_prog.c -L/usr/local/lib -llibcommon 是给予 /usr/bin/ld: 找不到 -llibcommon.so 收集