我想分配并初始化一大块连续的内存(~1GB),然后将其标记为只读并分叉多个(比如几十个)将使用它的子进程,而不制作自己的内存副本(机器没有足够的内存().
我是否正确地认为如果我malloc像往常一样将内存标记为只读mprotect(addr, size, PROT_READ),然后fork,这将允许子进程安全地使用内存而不会导致它被复制?(假设我确保在mprotect调用后没有尝试写入分配的内存).
编辑:感谢您的所有答案.
一个后续问题 - 我正在计划使用shmget,但我认为它已经使用mm,因此仅限于较小的分配(请参阅本页的" 限制"部分).例如/proc/sys/kernel/shmmax,服务器上的32MB我正在使用这个.但我想要1GB的连续内存.我错了这个限制吗?
可能重复:
Java类中的线程安全性
我在实践中阅读Java并发性,并且我找到了一个令我困惑的例子.
作者声明这个类不是线程安全的
public class MutableInteger {
private int number;
public int getInt() {
return number;
}
public void setInt(int val) {
number = val;
}
}
Run Code Online (Sandbox Code Playgroud)
并且他们还声明只同步一个方法(例如setter)不会; 你必须同步两者.
我的问题是:为什么?不会同步setter吗?
我正在用 python 开发一个科学计算工具,它应该能够在 NUMA 共享内存环境中的多个内核上分配工作。我正在研究最有效的方法。
由于 python 的全局解释器锁,线程 - 不幸的是 - 不在游戏中,这让叉子成为我唯一的选择。对于进程间通信,我想我的选择是管道、套接字或 mmap。如果此列表中缺少某些内容,请指出。
我的应用程序将需要在进程之间进行相当多的通信,并访问一定数量的公共数据。我主要关心的是延迟。
我的问题:当我 fork 一个进程时,它的内存会位于它分配到的核心附近吗?作为写入时 *nix 副本中的 fork,最初我认为情况并非如此。我是否想强制复制以加快内存访问速度,如果是这样,最好的方法是什么?如果我使用 mmap 进行通信,该内存是否仍可以分布在核心上还是位于单个核心上?是否有透明地重新定位数据以优化访问的过程?有没有办法直接控制物理分配,或者有办法请求有关分配的信息以帮助优化?
在更高的层次上,这些东西中哪些是由我的硬件决定的,哪些是由操作系统决定的?正在买高端多路机,怀疑AMD皓龙和英特尔至强。特定硬件对上述任何问题的影响是什么?
我有一个多进程python应用程序(进程由uwsgi生成),需要在RAM中存储变量,然后从几个不同的进程读取和更新这些变量.我知道有很多可用的缓存选项,但我发现的所有选项都只能存储字符串.是否有可能不同的python进程访问相同的虚拟内存,从而共享数据而无需转换它甚至复制它?
我想在共享内存中创建一个unordered_map.我正在使用allocator来达到目的.
代码
void *addr;
void *pool;
int shmid;
template<class T>
class MyPoolAlloc {
private:
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template<class X>
struct rebind
{ typedef MyPoolAlloc<X> other; };
MyPoolAlloc() throw() {
}
MyPoolAlloc(const MyPoolAlloc&) throw() {
}
template<class X>
MyPoolAlloc(const MyPoolAlloc<X>&) throw() {
}
~MyPoolAlloc() throw() {
}
pointer address(reference __x) const { return &__x; }
const_pointer address(const_reference __x) const { …Run Code Online (Sandbox Code Playgroud) 我的问题是,当一个进程异常终止时(通过信号,它可能是SIGKILL,所以我们不能拦截它),是否有任何保证的顺序或原子性,其资源被释放?特别是,我对文件锁和共享内存感兴趣.
例如:
1)如果过程是坚持2个文件锁和异常终止,是它在所有可能的另一个进程试图锁定看到一个文件被锁定相同的文件和另一个被解锁?或者从其他进程的角度来看,释放文件锁原子的过程是什么?
如果它不是原子的,那么是否存在至少一个预定义的顺序,其中文件锁将被终止进程释放(例如,它们最初被锁定的顺序相反)?
2)我想使用文件锁来确保正确的共享内存初始化 - 映射到共享内存的进程将保持共享锁,并且想要映射到同一共享内存段的新进程将尝试测试该锁以查看是否需要执行初始化(如果需要,我可以在以后提供更多详细信息).
但是同样的问题出现在这里:如果一个持有文件锁并且也映射到共享内存段的进程异常终止,那么在共享内存自动取消映射后,另一个进程是否仍然可以看到文件锁被锁定?或者是从其他进程的角度取消映射共享内存段并解锁文件原子?
我正在尝试将程序代码放入并执行到共享内存区域.初始化和分配共享内存以及将shellcode复制到"新"内存按预期工作,但是一旦我尝试执行它,它就不起作用.有谁知道问题可能是什么?
我想那write(1, 0x6000d8, 13) = -1 EFAULT (Bad address)可能是错误?可能是什么导致了这个?
我包含了代码和stract错误输出.C代码基于Adam Rosenfield在本期杂志中的回答.
C代码
#include <string.h>
#include <sys/mman.h>
// My own shellcode, obtained through objdump
// works on its own (a hello world-program)
const char shellcode[] = "\xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x48\xbe\xd8\x00\x60\x00\x00\x00\x00\x00\xba\x0d\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05";
int main(int argc, char **argv)
{
void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
memcpy(mem, shellcode, sizeof(shellcode));
mprotect(mem, sizeof(shellcode), PROT_READ|PROT_WRITE|PROT_EXEC);
int (*func)();
func = (int (*)())mem;
(int)(*func)();
munmap(mem, sizeof(shellcode));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Strace日志
execve("./memory", ["./memory"], [/* 17 …Run Code Online (Sandbox Code Playgroud) 我有一个复杂的 python 对象,内存大小约为 36GB,我想在多个单独的 python 进程之间共享它。它作为 pickle 文件存储在磁盘上,目前我为每个进程单独加载该文件。我想共享这个对象,以便在可用内存量的情况下并行执行更多进程。
从某种意义上说,该对象用作只读数据库。每个进程每秒都会发起多次访问请求,而每次请求只是针对一小部分数据。
我研究了像 Radis 这样的解决方案,但我发现最终数据需要序列化为简单的文本形式。此外,将 pickle 文件本身映射到内存应该没有帮助,因为每个进程都需要提取它。所以我想到了另外两种可能的解决方案:
有没有一种简单的方法来实施这些解决方案?也许对于这种情况有更好的解决方案?
非常感谢!
我有一个使用共享内存的父子进程。孩子每秒将数据放入共享内存约 10 次。父母和孩子在写/读时使用信号量来锁定资源。这个解决方案工作了几个小时,然后我开始收到警告:
PHP 警告:sem_acquire():无法获取密钥 0x4101f1fb:第 350 行上的 script.php 中的参数无效
PHP 警告:sem_release():SysV 信号量 140105644163240(密钥 0x4101f1fb)当前不在脚本 34.php 中获取
看起来脚本超过了某个限制并且信号量被破坏了,但是我在ipcs 中找不到任何关于当前限制/使用的内容。
我也尝试使用sem_get以获得新的信号量 ID,但我无法通过共享内存将其传递给孩子shm_put_var不使用资源。
在长时间运行的进程中处理信号量的最佳方法是什么?
有没有办法让SharedMemoryPython创建的对象在进程之间持久存在?
如果在交互式 python 会话中调用以下代码:
>>> from multiprocessing import shared_memory
>>> shm = shared_memory.SharedMemory(name='test_smm', size=1000000, create=True)
Run Code Online (Sandbox Code Playgroud)
/dev/shm/它在 Linux 机器上创建一个文件。
ls /dev/shm/test_smm
/dev/shm/test_smm
Run Code Online (Sandbox Code Playgroud)
但是当 python 会话结束时,我得到以下信息:
/usr/lib/python3.8/multiprocessing/resource_tracker.py:216: UserWarning: resource_tracker: There appear to be 1 leaked shared_memory objects to clean up at shutdown
warnings.warn('resource_tracker: There appear to be %d
Run Code Online (Sandbox Code Playgroud)
并且test_smm消失了:
ls /dev/shm/test_smm
ls: cannot access '/dev/shm/test_smm': No such file or directory
Run Code Online (Sandbox Code Playgroud)
那么有没有什么方法可以让Python中创建的共享内存对象在进程运行中持久存在呢?
使用Python 3.8运行