Python 3.13 embedded in Android,How to Attach Android sub-thread? (original) (raw)

I’m trying to embed Python 3.13t(–disable-gil) into an Android app, and I’m calling the following code in the JNI called by the main thread

extern "C"
JNIEXPORT jint JNICALL
Java_com_test_cpyvm_MainActivity_runPython(JNIEnv *env, jobject thiz, jstring home,
                                             jstring run_module) {
    PyConfig config;
    PyStatus status;
    PyConfig_InitIsolatedConfig(&config);

    status = set_config_string(env, &config, &config.home, home);
    if (PyStatus_Exception(status)) {
        throw_status(env, status);
        return 1;
    }

    status = set_config_string(env, &config, &config.run_module, run_module);
    if (PyStatus_Exception(status)) {
        throw_status(env, status);
        return 1;
    }

    // Some tests generate SIGPIPE and SIGXFSZ, which should be ignored.
    config.install_signal_handlers = 1;

    status = Py_InitializeFromConfig(&config);
    if (PyStatus_Exception(status)) {
        throw_status(env, status);
        return 1;
    }
    PyConfig_Clear(&config);

    PyRun_SimpleString("import sys,sysconfig\n"
                       "print('Python version:', sys._is_gil_enabled())\n"
                       "print('Python version:', sysconfig.get_config_var(\"Py_GIL_DISABLED\"))\n");
    return 0;
}

Everything’s running great. It’s outputting normally.

Python version: False 
Python version: 1

When I created the new thread using the Java API (new Thread) and called the following function via JNI

extern "C"
JNIEXPORT jint JNICALL
Java_com_test_cpyvm_MainActivity_otherThread(JNIEnv *env, jobject thiz) {
    if (Py_IsInitialized()) {
        LOGE("Python is already initialized.");
       PyRun_SimpleString("from time import time,ctime\n"
                       "print('Today is', ctime(time()))\n");
    }
 
    return 0;
}

The program starts crashing because _PyRun_SimpleStringFlagsWithName->unicode_decode_utf8 -> PyUnicode_New -> _PyObject_MiMalloc (obmalloc.c:249)

244 void *
245 _PyObject_MiMalloc(void *ctx, size_t nbytes)
246 {
247 #ifdef Py_GIL_DISABLED
248    _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
249    mi_heap_t *heap = tstate->mimalloc.current_object_heap;
250    return mi_heap_malloc(heap, nbytes);
251 #else
252     return mi_malloc(nbytes);
253 #endif
254 }

How should I create the _PyThreadStateImpl object for the current thread, and can I execute Python bytecode in multiple threads of Android at the same time?