C++多線程中調用python api函數

來源:互聯網
上載者:User
今天看了近一天關於多線程的應用中,如何安全調用python方面的資料,開始的時候看的簡直頭大如鬥,被python語言的全域鎖(Global Interpreter Lock)、線程狀態(Thread State )等都有點繞暈了,後來經過各方面文章和協助文檔的相互參考,發現對於2.4/2.5版本,提供了PyGILState_Ensure, PyGILState_Release,哎,這下可方便大發了。

一、首先定義一個封裝類,主要是保證PyGILState_Ensure, PyGILState_Release配對使用,而且這個類是可以嵌套使用的。

#include <python.h>

class PyThreadStateLock
{
public:
    PyThreadStateLock(void)
    {
        state = PyGILState_Ensure( );
    }

    ~PyThreadStateLock(void)
    {
         PyGILState_Release( state );
    }
private:
    PyGILState_STATE state;
};

二、在主線程中,這樣處理

    // 初始化
    Py_Initialize();
    // 初始化線程支援
    PyEval_InitThreads();
    // 啟動子線程前執行,為了釋放PyEval_InitThreads獲得的全域鎖,否則子線程可能無法擷取到全域鎖。
    PyEval_ReleaseThread(PyThreadState_Get());
   
    // 其他的處理,如啟動子線程等
    ......
       
    // 保證子線程調用都結束後
    PyGILState_Ensure();
    Py_Finalize();
    // 之後不能再調用任何python的API

三、在主線程,或者子線程中,調用python本身函數的都採用如下處理

    {
        class PyThreadStateLock PyThreadLock;
        // 調用python的API函數處理
        ......
    }

呵呵,看這樣是否非常簡單了。

另外還有兩個和全域鎖有關的宏,Py_BEGIN_ALLOW_THREADS 和 Py_END_ALLOW_THREADS。這兩個宏是為了在較長時間的C函數調用前,臨時釋放全域鎖,完成後重新擷取全域鎖,以避免阻塞其他python的線程繼續運行。這兩個宏可以這樣調用

    {
        class PyThreadStateLock PyThreadLock;
        // 調用python的API函數處理
        ......

        Py_BEGIN_ALLOW_THREADS
        // 調用需要長時間的C函數
        ......
        Py_END_ALLOW_THREADS

        // 調用python的API函數處理
        ......
    }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.