Calling TBB 'parallel_for' in python thread

3

I have a custom c++ module for python that exposes functions, some of which use TBB (tbb21_015oss) to accelerate processing.

Until now, I had no problem when calling a TBB-accelerated function from Python (2.6.2) in a Win32 environment.

But now, I have a problem when calling such a function from a Python thread (created by using threading.Thread class) - while calling the same function, from the main Python thread works fine.

Calling the function lead to application crash, with the following message :

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

TBB.dll base address is 0x03510000, and according to MSVC 2005 debugger, the crash happens in code from TBB's 'parallel_for.h', apparently in static void start_for::run( const Range& range, const Body& body, const Partitioner& partitioner ) when executing :

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

It seems that there's a NULL pointer being dereferenced.

FWIW, TBB is initialized by using the deferred initialization mechanism :

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

Is there way to make this work ? For example, does TBB need specific initialization to allow it being called from a 'custom' thread ?

c++
python
windows
tbb
asked on Stack Overflow May 11, 2011 by rotoglup • edited May 11, 2011 by rotoglup

1 Answer

2

With TBB 2.1, each external thread that uses TBB should first create its own task_scheduler_init object; a single global object will not work.

Later versions of TBB relaxed this requirement; now such a thread-specific initialization object is created implicitly if absent.

You might try whether mechanical replacement of tbb.dll with a more recent version will help you. Recompiling the mentioned C++ module with a recent version of TBB will be even better. Reworking the module to initialize TBB separately for each thread that invokes it (so that it works with an older version too), if not prohibited by design constraints, might make sense as well.

answered on Stack Overflow May 11, 2011 by Alexey Kukanov

User contributions licensed under CC BY-SA 3.0