上一章節,講解了我寫的一個簡單的python線程的例子。
今天的主要內容是:C++調用python時,出現的一些問題
前幾篇文章中,我有寫到如何在C++中調用python的一個小例子,在這裏,我就不再仔細的講解這一方面了,直接切入重點。
1:我想模仿python中main函數的寫法,調用 " Begin_voice() " 和 " End_voice() "兩個函數時,把C++程序當成 "time.sleep()"這部分。
C++中我用兩個按鈕控制這兩個pyhthon函數,如下圖所示形式表示
當點擊 "Begin_voice" 按鈕時,調用python中 對應的 " Begin_voice " 函數
當點擊 "End_voice " 按鈕時,調用python中對應的 "End_voice" 函數
當我運行程序時,發現了一個問題:
當我運行了 "Begin_voice"這個按鈕時,線程也不處於卡死的狀態,我以爲是python正在捕捉我的數據。
當我點擊 " End_voice " 按鈕時,發現我想要的數據 "循環代碼段區域" 一個也沒有存儲成功。
當時我就鬱悶了,這是爲什麼呢,怎麼存儲不成功呢?
後來我開始查看python代碼,當我在python的下面代碼中添加了一句 代碼時,才發現了問題
當我的 開啓線程 代碼寫成這樣子的時候,只能捕獲到5s的數據,當我不寫時,1s的數據都捕獲不到。
我才明白了,當在python環境中直接使用時,不會出現問題。
只有在C++中調用python代碼時,當這個函數結束的時候,這個線程也就意味着結束。
因爲 "time.sleep" 代表的是讓主線程等待子線程。
後來,我就查閱了python的線程相關資料,需要把這句 "time.sleep(5)" 代碼,替換成 python線程的自然結束。
也就是代碼: " p.join() "
只有這樣,纔會一直運行線程,不會出現C++調用函數結束後,python的線程也就結束的結果了。
2:C++調用python時,出現了死循環現象?
解決了第一個問題後,我再次運行C++代碼時,發現了更嚴重的問題。
點擊 " Begin_voice " 按鈕時,C++界面處於死循環狀態了!
後來我調試C++代碼發現,C++程序就開始處於等待狀態,一直等待python函數的結束。通俗的說,死到這個函數裏面了。
但是,我的python程序是想等到線程的自然結束。
顯然兩種邏輯出現了矛盾。
調試代碼,發現了,在下面這句代碼中一直等待
//獲取返回結果
PyObject *pReturn = PyEval_CallObject(m_pFunc_BeginVoice , pArgs);
因爲我的python中沒有任何結束的標誌,所以,該程序就一直在運行,根本停不下來
所以,我理解的 C++ 相當於 " time.sleep() " 這個想法是錯誤的!
3:C++調用python線程的時,在C++中開啓一個線程調用,保證程序不被處於卡死狀態時,出現的問題?
理解思路:
C++在調用python的函數時,需要開啓一個線程,保證了程序不被處於卡死的狀態。
當需要結束線程的時候,再調用 "End_voice " 這個函數控制裏面的 g_flage變量。
看樣子邏輯應該是這樣子的,可是實際做的時候卻不是這個樣子的。
實際代碼中,當我開啓線程讀數據後,想要關閉線程,調用 "End_voice"時,會有崩潰的問題。
原因是:C++調用的一個python程序正在運行,同時訪問一個正在運行的文件,會出現內存衝突的問題。
至於,C++中線程調用函數運行,這個是一個非常基礎的內容,我就不再過多的描述了。
4:解決上述問題的方法
因爲python中使用一個全局變量控制線程的結束的,想要在C++調用的時候,使用和python中main一樣的流程是不可能的。
在這裏,我想到了一個方法,讓python和C++同時訪問一個文件。同時對一個文件進行操作,在這個文件中設置標誌位,根據設置的標誌位來判斷是否需要停止線程。
有的人看到這裏,就會想問:幹嘛這麼麻煩,直接在python中線程裏寫成一個固定的值,當達到這個條件時,直接結束線程不得了嘛?
我想說的是:我之所以使用這樣的方式,是因爲我想用python線程調用百度的語音轉文本的接口,想讓外界控制結束錄製,不能再線程中直接固定住退出值,只能這麼麻煩。
後面,我會講到在python線程中使用百度API出現的各種問題。
設定一箇中間文件 xx.ini文件。
python文件一直訪問該文件中的內容,不做任何修改的操作。
C++文件 做讀和寫的操作。
爲什麼C++文件需要做寫的操作?
因爲我是在C++中需要控制何時結束線程的。
我可以這麼設置這個ini文件
[setflage]
flage = 0
當flage = 0 時,python程序就一直執行線程程序。
只有C++程序將 flage 修改成 1 時,python的線程才自動結束。
如此就可以用外界C++程序調用python線程結束了。
在此,我僅提供思路。代碼量太大了,上一堆代碼還不如有一個好思路。獲取大家可以根據我的思路開發出更好的邏輯來。
今天的講解就到這裏結束了,如果有不懂的問題,我們可以一起交流。
下節內容,我會講到如何在python線程中使用百度API抓取聲音,並且在C++中的程序裏調用成功