повышение оболочки сна Python вызывает сон всей программы Python - PullRequest
2 голосов
/ 25 декабря 2011

У меня есть многопоточная библиотека, в которой я вызываю sleep (3) в разных потоках.я написал для него привязки Python с использованием Boost Python.теперь похоже, что Boost Python не работает с функцией сна (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 ()».

1 Ответ

1 голос
/ 25 декабря 2011

Прежде всего, я видел, что функция time.sleep в python не использует системный вызов sleep(3). он использует вызов времени ожидания select(2) на stdin (в функции "floatsleep"), чтобы его можно было прервать.

Однако я также обнаружил, что если вы напишите оболочку с Py_BEGIN_ALLOW_THREADS и Py_END_ALLOW_THREADS вокруг функции модуля наддува, явление, похоже, исчезнет.

Итак, вот новый код модуля буста, который позволяет многопоточность с sleep(3) вызовами:

#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);
}
...