Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python GIL:表达式中的所有参与者是否在表达式的持续时间内都增加了ref count? 让我说我有一个简单的C++类: class Widget { public: Widget() : x(1) { } void sleep() { sleep(x); } private: int x; };_Python_Gil - Fatal编程技术网

Python GIL:表达式中的所有参与者是否在表达式的持续时间内都增加了ref count? 让我说我有一个简单的C++类: class Widget { public: Widget() : x(1) { } void sleep() { sleep(x); } private: int x; };

Python GIL:表达式中的所有参与者是否在表达式的持续时间内都增加了ref count? 让我说我有一个简单的C++类: class Widget { public: Widget() : x(1) { } void sleep() { sleep(x); } private: int x; };,python,gil,Python,Gil,Widget::sleep阻塞,因此我想释放GIL,以便Python可以做一些其他事情,因此我将Widget::sleep包装在如下函数中: static void pyWidgetSleep(Widget& self) { PyThreadState* state = PyEval_SaveThread(); self.sleep(); PyEval_RestoreThread(state); } BOOST_PYTHON_MODULE(libnative)

Widget::sleep
阻塞,因此我想释放GIL,以便Python可以做一些其他事情,因此我将
Widget::sleep
包装在如下函数中:

static void pyWidgetSleep(Widget& self)
{
    PyThreadState* state = PyEval_SaveThread();
    self.sleep();
    PyEval_RestoreThread(state);
}
BOOST_PYTHON_MODULE(libnative)
{
    boost::python::class_<Widget>("Widget")
        .def("sleep", &pyWidgetSleep);
}
import libnative
import threading

class C:
    def __init__(self):
        self.x = libnative.Widget()
        self.sleeping = False

    def foo(self):
        self.sleeping = True
        self.x.sleep()

c = C()
t = threading.Thread(target=c.foo)
t.start()
while not c.sleeping:
    pass
del c.x
为完整起见,绑定代码如下所示:

static void pyWidgetSleep(Widget& self)
{
    PyThreadState* state = PyEval_SaveThread();
    self.sleep();
    PyEval_RestoreThread(state);
}
BOOST_PYTHON_MODULE(libnative)
{
    boost::python::class_<Widget>("Widget")
        .def("sleep", &pyWidgetSleep);
}
import libnative
import threading

class C:
    def __init__(self):
        self.x = libnative.Widget()
        self.sleeping = False

    def foo(self):
        self.sleeping = True
        self.x.sleep()

c = C()
t = threading.Thread(target=c.foo)
t.start()
while not c.sleeping:
    pass
del c.x
表达式中的所有参与者是否在表达式的持续时间内使其引用计数增加? 当在
c.foo
中使用时,
c.x
的唯一引用是
c
t.start()
后面的行可以方便地删除它。 由于
pywidgetleep
释放GIL,
del c.x
可能会减少对
小部件
实例的最后一次引用,从而导致未定义的行为


我无法在我的机器上实现这一突破,这似乎是一个很好的迹象,表明它能像我预期的那样工作,但引用计数并没有记录到如此清晰的程度 (或者,至少,我似乎找不到它)。CPython的相关部分似乎是
PyEval\u evalcodex
,它似乎将
Py\u incremf
应用于所有参数
参与函数调用,但我可能完全不参与该调用。

这个问题的答案是肯定的,它是安全的。这是Python中如何调用成员函数的结果。考虑在Python中实现<代码> WITGET < /C> >:

class Widget:
    def __init__(self):
        self.x = 1

    def sleep(self):
        os.sleep(self.x)
注意
Widget.sleep
的第一个参数是如何
self
?在调用期间,引用计数将增加!回想起来似乎很明显