Python的I2C模块 - malloc的Python中的特定版本失败 [英] Python C Module - Malloc fails in specific version of Python

查看:117
本文介绍了Python的I2C模块 - malloc的Python中的特定版本失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个Python模块在一个O_DIRECT背景下进行IO。一O_DIRECT的限制是必须读入一个4096字节边界上为2.4和2.5的内核,和2.6对准缓冲剂和最多会接受512任何倍数。

I'm writing a Python module to perform IO on a O_DIRECT context. One of the limitations of O_DIRECT is you must read into a buffer aligned on a 4096 byte boundary for 2.4 and 2.5 kernels, and 2.6 and up will accept any multiple of 512.

其明显的内存分配的候选人是 posix_memalign(无效** memptr,为size_t对齐,为size_t大小)

The obvious memory allocation candidate for this is posix_memalign(void **memptr, size_t alignment, size_t size)

在我的code,我分配一个区域,像这样:

In my code, I allocate an area like so:

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导入模块,这(以及未示出模块的其余部分),做工精细。

When I compile and import the module with python3.2, this (and the rest of the unshown module) work fine.

当我试图用python2.7相同的(我想preserve兼容性)它抛出PyErr_NoMemory例外, mem_ret == ENOMEM ,表示它无法分配。

When I attempt the same with python2.7 (I'd like to preserve compatibility) it throws the PyErr_NoMemory exception, and mem_ret == ENOMEM, indicating it was unable to allocate.

为什么我编译对Python版本会影响posix_memalign操作?

Why would the version of Python I compile against affect how posix_memalign operates?

操作系统:Ubuntu的LTS 12.04

OS: Ubuntu 12.04 LTS

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

Compiler: Clang + GCC Show same behaviour

更新

我现在有code的工作片,由于user694733结果
然而,它的工作原理其实有我更糊涂了:

I now have a working piece of code, thanks to user694733
However the fact that it works has me even more confused:

#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

任何人都可以解释为什么在不正确首块Python3下的作品,而不是2.7,更​​重要的是,为什么在正确第二块不Python3下工作吗?

Can anyone explain why the incorrect first block works under Python3, but not 2.7, and more importantly why the correct second block does not work under Python3?

更新2

越来越复杂了,已经入驻低于code的正确形式,我在4个不同版本的Python测试。

The plot thickens, having settled on the correct form of the code below, I tested on 4 different version of 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 :如预期这code运行结果
的Python 3.1 :这code运行如预期结果。
的Python 3.2 :这code生成 mem_ret == ENOMEM 返回NULL缓冲结果
的Python 3.3 :这code运行如预期

Under Python 2.7: This code operates as expected.
Under Python 3.1: This code operates as expected.
Under Python 3.2: This code generates mem_ret == ENOMEM and returns NULL for buffer
Under Python 3.3: This code operates as expected.

不包含在Ubuntu软件仓库的Python版本是从PPA安装在<一个href=\"https://launchpad.net/~fkrull/+archive/deadsnakes\">https://launchpad.net/~fkrull/+archive/deadsnakes

The Python versions not included in the Ubuntu repositories were installed from the PPA at https://launchpad.net/~fkrull/+archive/deadsnakes

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

If the version tagged Python binaries are to be believed, the versions I have installed are:

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

能在默认Python3分配使用宽UNI code标志是造成这个错误?如果是这样,怎么会这样?

Could the use of the wide-unicode flag in the default Python3 distribution be causing this error? If so, how is this happening?

为了清楚起见, ENOMEM 分配失败将会同)的任何变体的malloc(,甚至一些如发生简单的malloc(512)

For clarity, the ENOMEM failure to allocate will occur with any variant of malloc(), even something as simple as malloc(512).

推荐答案

对于一个快速解决方法,坚持 MMAP 而不是的malloc + memalign可

For a quick work-around, stick to mmap instead of malloc+memalign

这篇关于Python的I2C模块 - malloc的Python中的特定版本失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆