почему модуль __init__ в проекте django загружается дважды в одном и том же процессе? - PullRequest
5 голосов
/ 24 июня 2011

Я пытаюсь обернуть библиотеку c в интерфейс Python высокого уровня с Boost.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 в конструкторе и os.getpid () в init . Вот результат процесса 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__ снова вызывается внутри того же процесса (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 может это сделать?

1 Ответ

2 голосов
/ 24 июня 2011

Поскольку он загружается через две разные записи в sys.path.Будьте последовательны в своем импорте;Я рекомендую импортировать модуль без через проект, например, import <app>.<module>.Конфигурирование контейнера WSGI так, чтобы вы не зависели от искажения manage.py в sys.path, поможет.

...