我正在尝试使用Boost.Python将c库包装在高级python接口中。 c库的一个客户端契约是其中一个句柄每个进程只能分配一次。我希望我可以通过使用全局模块在python端强制执行此合同。
这是我的django组件模块的__init__.py
。每个流程只能创建一次PyGenTL
!
import my_c_mod
import os
print "imager__init__()"
print os.getpid()
ptl = my_c_mod.PyGenTL()
稍微相关的Boost.Python代码
BOOST_PYTHON_MODULE(my_c_mod)
{
using namespace boost::python;
// Create the Python type object for our extension class and define __init__ function.
class_<PyGenTL>("PyGenTL")
.def("sys_info", &PyGenTL::SysInfo)
.def("list_cameras", &PyGenTL::ListCameras) //
.def("start_camera", &PyGenTL::StartCamera) //
;
}
PyGenTL::PyGenTL()
{
try {
std::cout << "PyGenTL ctor(): allocating GenTL Lib." << std::endl;
Detail::ThrowError(GCInitLib());
Detail::ThrowError(TLOpen(&hTL));
} catch (boost::exception& e) {
std::cerr << "PyGenTL ERROR! ";
std::cerr << boost::diagnostic_information(e);
std::cerr << std::endl;
}
}
请注意构造函数中的print语句和 init 中的os.getpid()。这是django进程的输出。请注意,在python的开头创建了两个进程,这就是创建两个PyGenTL
的原因。到现在为止还挺好。
C:\work\svn\sw\branches\python\GenTlServer>python manage.py runserver
imager__init__()
2264
PyGenTL ctor(): allocating GenTL Lib.
imager__init__()
2912
PyGenTL ctor(): allocating GenTL Lib.
Validating models...
0 errors found
Django version 1.3, using settings 'GenTlServer.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
现在,在页面视图中,__init__
在同一进程中被称为AGAIN(2912)
imager__init__()
2912
PyGenTL ctor(): allocating GenTL Lib.
ERROR (-1004): Requested module is in use.
PyGenTL ERROR! Requested module is in use.
[23/Jun/2011 18:02:22] "GET / HTTP/1.1" 500 76537
当然,通过在C端执行单例来解决我的特定问题,但是python的方法是什么?
答案 0 :(得分:2)
因为它是通过sys.path
中的两个不同条目加载的。对进口保持一致;我建议在没有的情况下导入模块,例如, import <app>.<module>
。配置WSGI容器以便您不依赖于manage.py
对sys.path
的重复操作会有所帮助。