C调用Python之多线程与traceback打印

简介: C调用Python之多线程与traceback打印

一、C多线程调用Python

1、参考如下文章:

2、示例代码

主线程中这样处理

  // 初始化
  Py_Initialize();
  if ( !Py_IsInitialized() ) 
    return
  // 初始化线程支持  
  PyEval_InitThreads();
  // 启动子线程前执行,为了释放PyEval_InitThreads获得的全局锁,否则子线程可能无法获取到全局锁。
  PyEval_ReleaseThread(PyThreadState_Get());
    
  // 其他的处理,如启动子线程等
  ......
    
  // 保证子线程调用都结束后
  PyGILState_Ensure();
  Py_Finalize();
  // 之后不能再调用任何python的API

在主线程,或者子线程中,调用python本身函数采用如下处理

  PyGILState_STATE state;
  state = PyGILState_Ensure();
  ...
  // 调用python的API函数处理
  ...
  PyGILState_Release(state);


二、打印traceback信息

1、参考

2、示例代码

std::string getPythonErrorInfo(void) {
    string errorMsg = "";
    PyObject *pType, *pValue, *pTraceback;
    PyErr_Fetch(&pType, &pValue, &pTraceback);
    if (pValue == nullptr) {
        return errorMsg;
    }
    if (pTraceback == nullptr) {
        errorMsg += PyUnicode_AsUTF8(pValue);
    } else {
        PyErr_NormalizeException(&pType, &pValue, &pTraceback);
        PyObject *pTraceModule = PyImport_ImportModule("traceback");
        if (pTraceModule != nullptr) {
            PyObject *pModuleDict = PyModule_GetDict(pTraceModule);
            if (pModuleDict != nullptr) {
                PyObject *pFunc = PyDict_GetItemString(pModuleDict, "format_exception");
                if (pFunc != nullptr) {
                    PyObject *errList = PyObject_CallFunctionObjArgs(pFunc, pType, pValue, 
                            pTraceback, nullptr, nullptr);
                    if (errList != nullptr) {
                        int listSize = PyList_Size(errList);
                        for (int i = 0; i < listSize; ++i) {
                            auto item = PyList_GetItem(errList, i);
                            errorMsg += PyUnicode_AsUTF8(item);
                        }
                        Py_XDECREF(errList);
                    }
                    Py_XDECREF(pFunc);
                }
                Py_XDECREF(pModuleDict);
            }
            Py_XDECREF(pTraceModule);
        }
    }
    Py_XDECREF(pType);
    Py_XDECREF(pValue);
    Py_XDECREF(pTraceback);
 
    return errorMsg;
}

目录
相关文章
|
18天前
|
数据采集 存储 安全
如何确保Python Queue的线程和进程安全性:使用锁的技巧
本文探讨了在Python爬虫技术中使用锁来保障Queue(队列)的线程和进程安全性。通过分析`queue.Queue`及`multiprocessing.Queue`的基本线程与进程安全特性,文章指出在特定场景下使用锁的重要性。文中还提供了一个综合示例,该示例利用亿牛云爬虫代理服务、多线程技术和锁机制,实现了高效且安全的网页数据采集流程。示例涵盖了代理IP、User-Agent和Cookie的设置,以及如何使用BeautifulSoup解析HTML内容并将其保存为文档。通过这种方式,不仅提高了数据采集效率,还有效避免了并发环境下的数据竞争问题。
如何确保Python Queue的线程和进程安全性:使用锁的技巧
|
5天前
|
API Python
探索Python中的多线程编程
探索Python中的多线程编程
27 5
|
16天前
|
调度 Python
Python 中如何实现多线程?
【8月更文挑战第29天】
38 6
|
25天前
|
数据采集 Java Python
Python并发编程:多线程(threading模块)
Python是一门强大的编程语言,提供了多种并发编程方式,其中多线程是非常重要的一种。本文将详细介绍Python的threading模块,包括其基本用法、线程同步、线程池等,最后附上一个综合详细的例子并输出运行结果。
|
23天前
|
数据采集 Java Python
Python并发编程:多线程(threading模块)
本文详细介绍了Python的threading模块,包括线程的创建、线程同步、线程池的使用,并通过多个示例展示了如何在实际项目中应用这些技术。通过学习这些内容,您应该能够熟练掌握Python中的多线程编程,提高编写并发程序的能力。 多线程编程可以显著提高程序的并发性能,但也带来了新的挑战和问题。在使用多线程时,需要注意避免死锁、限制共享资源的访问,并尽量使用线程池来管理和控制线程。
|
1月前
|
开发工具 计算机视觉 Python
大恒相机 - Python 多线程拍摄
大恒相机 - Python 多线程拍摄
32 1
|
1月前
|
调度 Python
|
17天前
|
数据采集 Java Python
python 递归锁、信号量、事件、线程队列、进程池和线程池、回调函数、定时器
python 递归锁、信号量、事件、线程队列、进程池和线程池、回调函数、定时器
|
21天前
|
安全 Java Python
Python 中的多线程
【8月更文挑战第24天】
16 0
|
23天前
|
数据处理 Python
解锁Python多线程编程魔法,告别漫长等待!让数据下载如飞,感受科技带来的速度与激情!
【8月更文挑战第22天】Python以简洁的语法和强大的库支持在多个领域大放异彩。尽管存在全局解释器锁(GIL),Python仍提供多线程支持,尤其适用于I/O密集型任务。通过一个多线程下载数据的例子,展示了如何使用`threading`模块创建多线程程序,并与单线程版本进行了性能对比。实验表明,多线程能显著减少总等待时间,但在CPU密集型任务上GIL可能会限制其性能提升。此案例帮助理解Python多线程的优势及其适用场景。
26 0