0

我使用 boost.python 库构建的 python 扩展的行为非常奇怪。即,在这段代码中:

import my_ext

j = 0
while j<5:
    print j
    my_ext.do_something(j)
    j = j + 1

我没有看到 j 被打印出来,而扩展代码 ( my_ext.do_something(j)) 正在为不同的 j 做一些工作(比如说打印第 j 个文件)。此外,它只打印 j = 0 和 j = 1 的 2 个文件,然后整个脚本完成,没有错误或其他通知。

所有这一切让我觉得代码是并行执行的(多线程),但没有正确处理这种并行化。我想这可能与我构建的 boost.python 库默认使用 --threading=multi 选项有关。但是,尝试使用选项 --threading=single 进行重建不会产生任何效果,它仍然被构建为多线程库。这篇文章http://mail.python.org/pipermail/cplusplus-sig/2010-October/015771.html 报告了类似的构建过程问题,但没有得到答复。

所以我的问题是如何构建 boost 库和 boost.python 特别是单线程的。或者,问题可能与 boost.python 库的单/多线程以外的其他问题有关。

附加信息:我正在使用 cygwin、boost_1.50.0、python2.6,我的操作系统是 Win 7,具有多核 CPU 和 nvidia vram(后一种硬件可能支持我的扩展程序的多线程执行而不让我知道)。

4

1 回答 1

1

Boost.Python 往往是 Boost 构建系统中的一个特例,因为它与 Python 构建的 Python 版本和配置相耦合。例如,如果 Python 是在没有调试的情况下构建的,那么 Boost.Python 将在没有调试的情况下构建,即使 Boost 被明确告知构建一个调试变体。我相信 threading 属性也是如此,因为它会通过 include 间接pyconfig.h包含Python.h.

Python 默认在单线程中运行程序,无论 Python 是否使用线程支持构建。Boost.Python 不会改变这种行为。作为一般经验法则,只有在需要并发性时,线程才会成为 Boost.Python 的一个因素。例如,如果my_ext.do_something()要将一个大文件读入内存,那么最好在不锁定解释器的情况下执行读取。

考虑从扩展的简化实现开始,然后对其进行扩展。例如,当我构建my_ext为:

#include <iostream>
#include <boost/python.hpp>

void do_something(unsigned int j)
{
  std::cout << "do_something(): " << j << std::endl;
}

BOOST_PYTHON_MODULE(my_ext)
{
  namespace python = boost::python;
  python::def("do_something", &do_something);
}

我的测试脚本:

import my_ext

for j in xrange(5):
    print j
    my_ext.do_something(j)

产生:

0
做某事():0
1
做某事():1
2
做某事():2
3
做某事():3
4
做某事():4

另一种方法是构建 Python 和 Boost.Python 的调试版本,然后使用调试器逐步执行程序。可以在此处找到有关调试版本的更多信息。

于 2013-03-25T16:53:38.460 回答