在Python线程中调用TBB的'parallel_for

3 投票
1 回答
1256 浏览
提问于 2025-04-16 17:25

我有一个自定义的C++模块,可以在Python中使用,里面有一些函数是用TBB(tbb21_015oss)来加速处理的。

到目前为止,我在Win32环境下从Python(2.6.2)调用这些用TBB加速的函数时没有遇到任何问题。

但是现在,我在从一个Python线程(用threading.Thread类创建的)调用这样的函数时遇到了问题——而从主Python线程调用同样的函数却没有问题。

调用这个函数导致应用程序崩溃,出现了以下信息:

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

TBB.dll的基本地址是0x03510000,根据MSVC 2005调试器的提示,崩溃发生在TBB的'parallel_for.h'中的代码里,显然是在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));

看起来是有一个空指针被解引用了。

顺便提一下,TBB是通过延迟初始化机制来初始化的:

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

有没有办法让这个工作正常?比如说,TBB是否需要特定的初始化,以便可以从一个“自定义”的线程中调用?

1 个回答

2

在TBB 2.1版本中,每个使用TBB的外部线程都需要先创建自己的task_scheduler_init对象;一个全局的对象是无法工作的。

在后来的TBB版本中,这个要求放宽了;现在如果没有这个特定于线程的初始化对象,系统会自动创建一个。

你可以尝试把tbb.dll替换成更新版本,看看是否能解决问题。用更新版本的TBB重新编译提到的C++模块会更好。如果设计上没有限制,重新调整模块,让每个调用它的线程单独初始化TBB(这样即使在旧版本上也能工作),也是个不错的选择。

撰写回答