Python线程在C++应用嵌入式解释器中不运行

6 投票
3 回答
3719 浏览
提问于 2025-04-15 16:14

我有一个C++应用程序,它使用嵌入的Python解释器和Python C API。这个程序可以通过PyRun_SimpleFile和PyObject_CallMethod来执行Python文件和源代码。

现在我有一段Python源代码,它里面有一个工作线程,这个线程是从threading.Thread类继承而来的,并且有一个简单的run方法重写:

import time
from threading import Thread
class MyThread(Thread):
    def __init__(self):
        Thread.__init__(self)

    def run(self):
        while True:
            print "running..."
            time.sleep(0.2)

问题是“running”这个信息在控制台里只打印了一次。

我该如何确保Python线程能够和我的C++应用程序的图形界面循环并行运行呢?

提前谢谢你,

保罗

3 个回答

1

虽然这个话题已经有点老了,但我觉得我的回答可能对遇到同样问题的其他人有帮助。

我两天前也遇到了同样的问题,我在网上搜索,找到了这个讨论,但@Reuille的解决方案对我没用。

现在我想分享一个我刚刚找到的解决方法:你需要在你的Python脚本中运行

app.exec()

而不是在你的C++主函数里。这是个奇怪的bug。

补充说明:你可以在我的 项目中看到我修复的详细信息。

2

主线程在干什么呢?它只是把控制权交还给你的C++应用吗?如果是这样的话,记得在主线程没有运行任何Python代码时释放GIL(全局解释器锁),否则你的其他Python线程会因为等着GIL被释放而停滞不前。

最简单的方法是使用Py_BEGIN_ALLOW_THREADS和Py_END_ALLOW_THREADS这两个宏。

详细信息可以查看文档:http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock

3

我之前也遇到过类似的问题,找到了解决办法。我知道这个讨论已经有点时间了,但如果有人还在想这个问题……这里有一段代码示例,可以满足你的需求。

#include <Python.h>

#include <iostream>
#include <string>
#include <chrono>
#include <thread>

int main()
{
    std::string script =
        "import time, threading                        \n"
        "" 
        "def job():                                    \n"
        "    while True:                               \n"
        "         print('Python')                      \n"
        "         time.sleep(1)                        \n"
        ""
        "t = threading.Thread(target=job, args = ())   \n"
        "t.daemon = True                               \n"
        "t.start()                                     \n";

    PyEval_InitThreads();
    Py_Initialize();

    PyRun_SimpleString(script.c_str());

    Py_BEGIN_ALLOW_THREADS

    while(true)
    {
        std::cout << "C++" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    Py_END_ALLOW_THREADS

    Py_Finalize();

    return 0;
}

撰写回答