Почему функции Python собирают мусор? - PullRequest
3 голосов
/ 08 сентября 2011

У меня есть библиотека C ++, которая использует обратные вызовы Python. Обратный вызов, т.е. PyObject *, хранится в объекте класса UnaryFunction, и конструктор Py_INCREFs его. Деструктор Py_XDECREFs это. Это проблема. На этом DECREF переводчик ошибается.

Мое решение состоит в том, чтобы просто НЕ УКАЗАТЬ это, но это кажется неправильным. Как правильно использовать счетчик ссылок для функции в INC / DEC и, что более важно, почему интерпретатор пытается собрать тело функции, когда есть другие живые ссылки на него?

Изменить: В Linux вместо segfault я получаю ошибку подтверждения, которая говорит:

python: Objects/funcobject.c:442: func_dealloc: Assertion 'g->gc.gc_refs != (-2)' failed.

Ответы [ 2 ]

1 голос
/ 08 сентября 2011

Сбой не обязательно означает, что он пытается собрать использованный объект.Это также может означать, что вы вызываете код Python без блокировки интерпретатора.

Вызов Py_XDECREF в деструкторе заставляет меня думать, что у вас что-то вроде этого:

void MyCallback(myfunc, myarg)
{
    ...
    PyGILState_STATE gilstate = PyGILState_Ensure();
    try {
            myfunc(myarg);
    } catch (...) {
        ...
    }
    PyGILState_Release(gilstate);

    // myfunc goes out of scope here --> CRASH because we no longer own the GIL
}

с простым решением:

...
try {
    scopefunc = myfunc;
    myfunc = emptyfunc();
    scopefunc(myarg);
} ...
0 голосов
/ 09 сентября 2011

Похоже, что Py_INCREF просто не увеличивает значение refcount.

...