I'm trying to wrap a c library in a high-level python interface with Boost.Python. One of the client contracts of the c library is that one of the handles can only be allocated once per-process. I was hoping I could enforce this contract on the python side by using a module global.
Here is my django component module's __init__.py
. PyGenTL
must only be created once per process!
import my_c_mod
import os
print "imager__init__()"
print os.getpid()
ptl = my_c_mod.PyGenTL()
Slightly relevant Boost.Python code
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::ThrowErro开发者_运维知识库r(GCInitLib());
Detail::ThrowError(TLOpen(&hTL));
} catch (boost::exception& e) {
std::cerr << "PyGenTL ERROR! ";
std::cerr << boost::diagnostic_information(e);
std::cerr << std::endl;
}
}
Note the print statements in the constructor, and os.getpid() in init. Here is the output from the django process. Note that two processes are created at the start of python, which is why two PyGenTL
s are created. So far, so good.
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.
Now, during page view, __init__
gets called AGAIN within the same process (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
Sure, there is a work around for my particular problem by enforcing the singleton on the C side, but what is the python way to do it?
Because it's being loaded via two different entries in sys.path
. Be consistent about your imports; I recommend importing the module without going through the project, e.g. import <app>.<module>
. Configuring a WSGI container so that you're not dependent on manage.py
's mangling of sys.path
will help.
精彩评论