Вызов TBB «parallel_for» в потоке Python

У меня есть собственный модуль C++ для Python, который предоставляет функции, некоторые из которых используют TBB (tbb21_015oss) для ускорения обработки.

До сих пор у меня не было проблем с вызовом функции с ускорением TBB из Python (2.6.2) в среде Win32.

Но теперь у меня возникла проблема при вызове такой функции из потока Python (созданного с использованием класса threading.Thread) — при вызове той же функции из основного потока Python все работает нормально.

Вызов функции приводит к сбою приложения со следующим сообщением:

First-chance exception at 0x03522e96 in python.exe:
0xC0000005: Access violation reading location 0x000000c8.

Базовый адрес TBB.dll — 0x03510000, и, согласно отладчику MSVC 2005, сбой происходит в коде из «parallel_for.h» TBB, по-видимому, в static void start_for::run( const Range& range, const Body& body, const Partitioner& partitioner ) при выполнении:

start_for& a = *new(task::allocate_root(context)) start_for(range,body,const_cast<Partitioner&>(partitioner));

Кажется, разыменовывается указатель NULL.

FWIW, TBB инициализируется с использованием механизма отложенной инициализации:

// at 'global' scope
tbb::task_scheduler_init g_tbbinit(tbb::task_scheduler_init::deferred);  
...
// in a function
g_tbbinit.initialize();

Есть ли способ сделать эту работу? Например, требуется ли специальная инициализация TBB, чтобы его можно было вызывать из «пользовательского» потока?


person rotoglup    schedule 11.05.2011    source источник
comment
@Ugo - обновленный вопрос для добавления дополнительной информации   -  person rotoglup    schedule 11.05.2011


Ответы (1)


В TBB 2.1 каждый внешний поток, использующий TBB, должен сначала создать свой собственный объект task_scheduler_init; один глобальный объект не будет работать.

Более поздние версии TBB ослабили это требование; теперь такой объект инициализации для конкретного потока создается неявно, если он отсутствует.

Вы можете попробовать, поможет ли вам механическая замена tbb.dll на более новую версию. Перекомпилировать упомянутый модуль C++ с последней версией TBB будет еще лучше. Также может иметь смысл переработка модуля для инициализации TBB отдельно для каждого вызывающего его потока (чтобы он работал и с более старой версией), если это не запрещено конструктивными ограничениями.

person Alexey Kukanov    schedule 11.05.2011
comment
спасибо, это похоже на то, что мне нужно, мне трудно понять это из документации tbb. Я попробую как можно скорее. - person rotoglup; 11.05.2011