【发布时间】:2016-10-23 12:16:28
【问题描述】:
我使用ctypes 为 C 库编写了 Python 包装器。一切正常,直到我尝试使用 threading 模块。
这是一个重现它的小例子:
foo.c
#include <stdlib.h>
#include <assert.h>
char *foo_init() {
char *result = (char*)malloc(sizeof(char));
assert(result);
return result;
}
char foo_get(const char* p) {
return *p;
}
void foo_set(char *p, char value) {
*p = value;
}
void foo_del(char *p) {
free(p);
}
foo.py
import threading
import ctypes
libfoo=ctypes.CDLL('foo.so')
libfoo.foo_init.restype = ctypes.c_void_p
libfoo.foo_get.restype = ctypes.c_char
class Foo:
def __init__(self):
self.__obj__ = libfoo.foo_init()
def get(self):
return libfoo.foo_get(self.__obj__)
def set(self, value):
libfoo.foo_set(self.__obj__, ctypes.c_char(value))
def __del__(self):
libfoo.foo_del(self.__obj__)
x = Foo()
x.set(b'x')
print(x.get())
def compute():
y = Foo()
y.set(b'y')
print(y.get())
t = threading.Thread(target=compute)
t.start()
t.join()
编译:
gcc -Wall -shared -o foo.so -fPIC foo.c
执行:
export LD_LIBRARY_PATH=.
python3 foo.py
结果:
b'x'
[1] 8627 segmentation fault python3 foo.py
我们在这里看到x.get() 打印正确,而y.get() 出现分段错误。因此,似乎存在与ctypes 和threading 相关的问题。
请注意,如果我将y 的初始化移到compute 函数之外,则程序会正常退出。
此外,每个操纵指针的函数都会产生分段错误(例如,如果我只保留 __init__ 和 __del__ 函数,仍然会发生崩溃)。
知道如何解决这个问题吗?
【问题讨论】:
-
您设置了错误的返回类型,并且您没有设置任何参数类型。修复这些问题,看看结果是否有所不同。
-
我应该使用什么返回类型?我尝试了 c_char_p,但随后出现错误 *** `python3' 中的错误:munmap_chunk(): invalid pointer: 0x00007fd25ec0da28 *** 根据文档,c_char_p 用于 NUL 终止的 char*,这里不是这种情况。
-
引用docs,“对于也可能指向二进制数据的通用字符指针,必须使用
POINTER(c_char)。”。 -
非常感谢,它解决了我的问题。我发布了一个带有代码修改的答案。
标签: python c multithreading segmentation-fault ctypes