2

我有一个多线程库,我在不同的线程中调用sleep(3) 。我已经使用 boost python 为它编写了 python 绑定。现在看起来 boost python 正在搞乱 sleep(3) 函数,因为它暂停了整个 python 程序等待。

请考虑我有这个 boostmod.cpp 文件

#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE( boostmod ) {
    def("waiter",&::sleep);
}

(你可以使用编译它:)

$ g++ -fPIC -shared boostmod.cpp `python-config --cflags --libs` -lboost_python -o boostmod.so

这是一个 python 测试文件 threadtest.py :

import time,sys,threading,boostmod
from ctypes import *
if __name__ == '__main__':
    libc = CDLL("libc.so.6") # this only works in linux
    for n in range(5):
         if sys.argv[1] == "boost":
            # this is slow
            threading.Thread(target=boostmod.waiter,args=(3,)).start()
         elif sys.argv[1] == "native":
            # this is fast
            threading.Thread(target=time.sleep,args=(3,)).start()
         elif sys.argv[1] == "ctypes":
            # this is fast
            threading.Thread(target=libc.sleep,args=(3,)).start()

结果如下:

$ time python threadtest.py boost
  real    0m15.030s
  user    0m0.024s
  sys     0m0.005s
$ time python threadtest.py native
  real    0m3.032s
  user    0m0.027s
  sys     0m0.003s
$ time python threadtest.py ctypes
  real    0m3.030s
  user    0m0.022s
  sys     0m0.008s

如果您观察以下情况:

$ watch -n1 ps -C python -L -o pid,tid,pcpu,state

您可以看到“native”和“ctypes”实际上建立了 5 个线程加上主线程,而“boost”案例只有一个线程。实际上,在“boost”情况下,“.start()”在“sleep()”函数内部阻塞。

4

1 回答 1

1

首先,我看到time.sleeppython中的函数没有使用系统调用sleep(3)。它使用on (在函数“floatsleep”中)的超时调用,select(2)stdin以便可以中断它。

但是,我还发现,如果您使用 boost 模块功能及其周围编写一个包装器,则该现象似乎会消失。Py_BEGIN_ALLOW_THREADSPy_END_ALLOW_THREADS

所以这是允许多线程sleep(3)调用的新 boost 模块代码:

#include <boost/python.hpp>
using namespace boost::python;
void waiter(int seconds) {
    Py_BEGIN_ALLOW_THREADS
    ::sleep(seconds);
    Py_END_ALLOW_THREADS
}
BOOST_PYTHON_MODULE( boostmod ) {
    def("waiter",&::waiter);
}
于 2011-12-25T15:57:08.963 回答