boost.python не поддерживает параллелизм?

Я пытаюсь обернуть часть кода на C ++ в python lib, используя boost.python, однако я обнаружил, что несколько экземпляров не могут работать одновременно:

код (C ++):

class Foo{ public: Foo(){} void run(){ int seconds = 2; clock_t endwait; endwait = clock () + seconds * CLOCKS_PER_SEC ; while (clock() < endwait) {} } }; BOOST_PYTHON_MODULE(run_test) { using namespace boost::python; class_("test", init()) .def("run", &Foo::run) ; } 

который компилируется с использованием CMake (CMake):

 add_library(run_test SHARED run_test.cpp) target_link_libraries(run_test boost_python python2.7) 

и протестирован с помощью следующего кода (Python):

 class Dos(threading.Thread): def run(self): printl('performing DoS attack') proc = test() proc.run() for i in range(5): t = Dos() t.start() 

Вывод показывает, что код распараллелен очень странным образом. Каждый stream должен занимать всего 2 секунды, а четыре streamа должны выполняться одновременно на моей четырехъядерной машине:

 [2011-11-04 13:57:01] performing DoS attack [2011-11-04 13:57:01] performing DoS attack [2011-11-04 13:57:05] performing DoS attack [2011-11-04 13:57:05] performing DoS attack [2011-11-04 13:57:09] performing DoS attack 

спасибо за помощь!

    One Solution collect form web for “boost.python не поддерживает параллелизм?”

    На что вы работаете, это глобальная блокировка интерпретатора python. GIL позволяет только один stream запускать в интерпретаторе python.

    Одним из преимуществ Boost.Python является то, что вы можете выпустить GIL, сделать C ++, а затем вернуть его, когда закончите. Это также несет ответственность. Python обычно выпускает GIL через регулярные промежутки времени, чтобы дать другим streamам возможность запускать. Если вы находитесь на C ++, это ваша работа. Если вы продолжаете хруст в течение 2 часов, удерживая GIL, вы заморозите весь интерпретатор.

    Это можно легко исправить с помощью небольшого обратного RAII:

     class releaseGIL{ public: inline releaseGIL(){ save_state = PyEval_SaveThread(); } inline ~releaseGIL(){ PyEval_RestoreThread(save_state); } private: PyThreadState *save_state; }; 

    Теперь вы можете изменить свой код так:

     class Foo{ public: Foo(){} void run(){ { releaseGIL unlock = releaseGIL(); int seconds = 2; clock_t endwait; endwait = clock () + seconds * CLOCKS_PER_SEC ; while (clock() < endwait) {} } } }; 

    ОЧЕНЬ важно отметить, что вы НЕ ДОЛЖНЫ касаться какого-либо кода на Python или данных на основе python или обращаться к интерпретатору, не удерживая GIL. Это приведет к сбою вашего интерпретатора.

    Также можно пойти в другую сторону. Нить, в настоящее время не содержащая GIL, может получить ее и выполнить вызовы на python. Это может быть stream, который ранее выпускал GIL, или тот, который начинался на c ++ и никогда не имел GIL. Вот для этого class RAII:

     class AcquireGIL { public: inline AcquireGIL(){ state = PyGILState_Ensure(); } inline ~AcquireGIL(){ PyGILState_Release(state); } private: PyGILState_STATE state; }; 

    Использование остается упражнением для ученика.

    Дополнительное примечание (я всегда забываю упомянуть об этом):

    Если вы собираетесь возиться с GIL в c ++, ваше определение модуля должно начинаться с этого кода:

     BOOST_PYTHON_MODULE(ModuleName) { PyEval_InitThreads(); ... } 
    Interesting Posts

    Как определить, подписан ли пользователь Firebase с использованием аутентификации facebook

    Как ARP обрабатывает перемещение IP-адреса на другое устройство?

    Мощность, возводимая в квадрат для отрицательных показателей

    Установка Java на Ubuntu / Linux

    Почему Firefox интерпретирует 100% -ное масштабирование по-разному для других браузеров?

    Должен ли я избегать использования методов set (Preferred | Maximum | Minimum) в Java Swing?

    Как форматировать строки, используя printf (), чтобы получить равную длину в выходе?

    В поле формы ввода в WebView не отображается мягкая клавиатура

    Oracle вставить, если не существует оператора

    FFmpeg сплит видео и слияние

    Автоматическая замена моей тире заставляет меня грустить

    Android: получить эскиз изображения на SD-карте, учитывая Uri оригинального изображения

    Разбор JSON с использованием Gson для Java

    Использование Либо для обработки сбоев в коде Scala

    Любой достойный текстовый механизм diff / merge для .NET?

    Давайте будем гением компьютера.