gpt4 book ai didi

Python C 模块 - Malloc 在特定版本的 Python 中失败

转载 作者:太空狗 更新时间:2023-10-29 20:31:31 25 4
gpt4 key购买 nike

我正在编写一个 Python 模块来在 O_DIRECT 上下文中执行 IO。 O_DIRECT 的限制之一是对于 2.4 和 2.5 内核,您必须读入对齐到 4096 字节边界的缓冲区,而 2.6 和更高版本将接受 512 的任何倍数。

明显的内存分配候选者是 posix_memalign(void **memptr, size_t alignment, size_t size)

在我的代码中,我分配了这样一个区域:

char *buffer = NULL;

int mem_ret = posix_memalign((void**)&buffer, alignment, size);

if (!buffer) {
PyErr_NoMemory();
return NULL;
}

/* I do some stuff here */

free(buffer);

当我用 python3.2 编译和导入模块时,这个(以及未显示的模块的其余部分)工作正常。

当我尝试对 python2.7 进行同样的操作(我想保持兼容性)时,它会抛出 PyErr_NoMemory 异常,并且 mem_ret == ENOMEM 表明它无法分配。

为什么我编译的 Python 版本会影响 posix_memalign 的运行方式?

操作系统:Ubuntu 12.04 LTS

编译器:Clang + GCC 显示相同的行为

更新

感谢 user694733,我现在有了一段可用的代码
然而,它有效的事实让我更加困惑:

#if PY_MAJOR_VERSION >= 3
char *buffer = NULL;

int mem_ret = posix_memalign((void**)&buffer, alignment, count);
#else
void *mem = NULL;

int mem_ret = posix_memalign(&mem, alignment, count);

char *buffer = (char*)mem;
#endif

谁能解释为什么不正确的第一个 block 在 Python3 下工作,而不是 2.7,更重要的是为什么正确的第二个 block 在 Python3 下不工作?

更新 2

情节变浓了,在确定了下面代码的正确形式后,我在 4 个不同版本的 Python 上进行了测试。

void *mem = NULL;

int mem_ret = posix_memalign(&mem, alignment, count);

char *buffer = (char*)mem;

if (!buffer) {
PyErr_NoMemory();
return NULL;
}

/* Do stuff with buffer */

free(buffer);

Python 2.7 下:此代码按预期运行。
Python 3.1 下:此代码按预期运行。
Python 3.2 下:此代码生成 mem_ret == ENOMEM 并为 buffer
返回 NULL在 Python 3.3 下:此代码按预期运行。

未包含在 Ubuntu 存储库中的 Python 版本是从位于 https://launchpad.net/~fkrull/+archive/deadsnakes 的 PPA 安装的

如果相信版本标记的 Python 二进制文件,我安装的版本是:

python2.7 
python3.1
python3.2mu (--with-pymalloc --with-wide-unicode)
python3.3m (--with-pymalloc)

在默认的 Python3 发行版中使用 wide-unicode 标志是否会导致此错误?如果是这样,这是怎么发生的?

为清楚起见,ENOMEM 分配失败将发生在 malloc() 的任何变体中,即使是像 malloc(512) 这样简单的东西>。

最佳答案

为了快速解决问题,坚持使用 mmap 而不是 malloc+memalign

关于Python C 模块 - Malloc 在特定版本的 Python 中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21458818/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com