如何判斷CTP的行情線程是否阻塞?
自己寫的CTP客戶端,有時候行情線程莫名其妙的就結束了(看記錄的行情數據,自從某個時間點以後就沒有了),看文檔才知道,可能是線程阻塞了。各位大俠,有什麼方法可以判斷交易或者行情線程阻塞啊?如果交易線程掛掉了,怎麼處理?有什麼解決方案?為謝!
補充一下:我把策略寫在行情回報函數中。有的時候就莫名其妙的宕掉了(行情數據不再更新),有的時候又是正常的。
正常的機制是創建一個消息隊列,API線程存入數據,另一個策略運行的線程讀取數據,但這樣產生的問題是增加了代碼複雜程度,因為消息隊列是中間層性質的,對行情處理效率有一點點影響但也不是很大,還有就是維護麻煩,尤其是一個一個策略單獨開發的模式下,不是有共用性很好的平台基礎的支撐,消息隊列的管理和使用經常是需要調整,一個策略跑了多個品種,但來了行情就全部的類對象都告知一遍,知道這不合理,但沒辦法,因為最後就是挑簡單的方式弄。但是,這種東西有一個好處,就是特別適合大批量數據的並行處理,比如一個策略跑了比較多的品種,或者一個策略一個品種但是添加了特別多的任務方式,或者複製文華商品指數的策略,同一時間點所處理或者所需要的行情越多,消息隊列的簡單並行處理也都能顯得極大的優勢,比如為了計算文華指數,同一時刻所有存在的行情的推送是無間隔依次遞交給你的,但你如果單序列處理的話,行情計算的累積時間不可小估,一條行情5ms,30個品種就是150ms了,所以這種情況使用消息隊列並且使用並行處理就很是很好的解決辦法。
還有一個但是的但是,這種模式並不需要全部策略都這麼套,還是複雜不好用,大部分策略情況在回調函數里來一個行情就立即處理的方法還是比較好的,簡單。500ms的允許計算量還是夠,你如果是在行情回調函數處阻塞了,你的行情處理時間必然是發生超過500ms情況,這個應該考慮優化了,但也有可能就是網速不穩定,你可以用肉眼看文華財經的閃動判別下網速問題。。。還有一個機制,就是行情會阻塞但是不會丟失,你一條數據處理花了3秒鐘,比如10點1分0秒0毫秒這條數據,處理完後是下一個tick而不是10點1分3秒0毫秒這個數據,所以,偶爾行情計算時間過長會造成線程的阻塞,頂多就是卡頓不順暢,但如果你的程序都阻塞停了,那就是阻塞特別特別長了。
好問題!
無論是CTP還是任何其它API,在使用它接收行情的時候,都有一條應當遵循的規則:無論API是通過事件或是其它任何機制把行情扔給你的接收代碼,你都不應該在API的那個線程上,處理任何與接收行情無關的邏輯。
這個規則的原因:我們不能對API所使用的線程模型,做任何的假設。如果我們佔用了API拋行情的線程,做了太多自己的事情,API很可能無法及時搶佔到線程,導致後續行情處理失敗。當發生這種事情時,API會怎麼處理,很可能超出我們的控制。比如,API可能決定,再也不發送後續的行情了。
問題很簡單,ctp的spi會創建一個線程用於網路IO並調用各種OnRtnxxx的回調函數。不要在這個主線程做業務處理工作,一般情況下是用一個隊列緩存這些回報。然後你自己創建一個線程用於處理這些回報。可以用加鎖的方法來保證線程安全,也可以用無鎖隊列;至於何時來處理這些報文,可以通過通知(管道,eventfd)的形式,也可以通過定時輪詢的形式,但不建議用條件變數,因為這麼干進程上下文切換太多了。
行情線程阻塞?沒有遇到過,你最好看看你的代碼實現吧,是在線程中加鎖了還是有信號量什麼的,由於沒有具體信息,所以很難給你解決,大概說一下
結論:Spi里不要寫邏輯,把策略代碼拿到別的線程去執行。
CTP的介面採用了回調機制。這種介面的優勢是當有事件(行情、報單和成交回報、查詢結果、市場變化)發生時,客戶端的OnRspXxxSpi回調函數會觸發,這樣可以直接在客戶端處理此事件,比輪詢方式要快且省資源。缺點呢,就是使用起來的學習成本會高一些,另外要注意多線程的應用。
實際上,CTP團隊在開發的時候已經考慮到了回調函數的使用方式了:
交易員 API 提供了二個介面,分別為 CThostFtdcTraderApi 和CThostFtdcTraderSpi。這兩個介面對 FTD協議進行了封裝,方 便客戶端應用程序的開發。
客戶端應用程序可以通過 CThostFtdcTraderApi 發出操作請求,通繼承CThostFtdcTraderSpi並重載回調函數來處理後台服務的響應。
交易員客戶端應用程序至少由兩個線程組成,一個是應用程序主線程,一個是交易員 API 工作線程。應用程序與交易系統的通訊是由 API 工作線程驅動的。
CThostFtdcTraderApi提供的介面是線程安全的,可以有多個應用程序線程同時發出請求。 CThostFtdcTraderSpi提供的介面回調是由 API 工作線程驅動,通過實現 SPI中的介面方法,可以從交易託管系統收取所需數據。 如果重載的某個回調函數阻塞,則等於阻塞了 API 工作線程,API 與交易系統的通訊會停止。因此,在 CThostFtdcTraderSpi 派生類的回調函數中,通常應迅速返回,可以利用將數據放入緩衝區或通過 Windows 的消息機制來實現。
我記得這份文檔是2008年發布的,各期貨公司和CTP群里應該能找到。應該說上期技術在技術文檔更新上很不給力,但實際發布出來的幾份文檔寫得還是可以的。
我引用的這份文檔是:
《交易託管系統交易員應用程序介面》
另外還有一份
《綜合交易平台API開發常見問題列表》
配合頭文件服用,基本可以解決CTP開發的問題。
我手頭的文檔都是第一個版本的,產品團隊後面也許發布過新的版本,可以在上期技術的網站找找:
sfit.com.cn
問期貨公司的人應該也能找到。
問題不太具體,可以提供具體的報錯信息,要不然可能性太多,難以具體回答。
我寫了數據伺服器,處理數據並且發送客戶端請求的數據。大體流程是,行情回調將數據壓入緩衝buffer。k線生成線程處理這些數據,併產生很多業務方面的回調,例如:新k觸發,行情重連等,這些回調會通過網路引擎通知給我們的交易客戶端。交易客戶端只負責交易邏輯。這樣客戶端任何時候都取到最正確的數據,尤其是指數(沒有數據伺服器就沒法維護指數數據)。
同樣遇到這個現象。
最初我是接受到行情後發送消息來處理行情,一直沒問題。
之後覺得這樣影響速度,就把策略寫在行情函數里。有一個策略稍微複雜一些,常發現行情斷了。在同一網路同時執行幾個模擬賬戶,各個賬戶會在不同時間斷掉,還以為交易所限制同一網址裡面鏈接過多的賬戶。之後在OnFrontDisconnected中寫日誌,顯示的斷線原因顯示「網路寫失敗」。後來在不同的網路上也斷,折騰了很久後來才明白是API阻塞了。因此簡單的指標計算可以寫在OnRtnDepthMarketData里,複雜的就發消息或創建新的線程來做。謝邀,這種可以寫在開拓者論壇裡面,或者直接問客服,可能我程序比較簡單,貌似還木有遇到這種問題
瀉藥。
關於ctp這一塊的撰寫比較少,所以也不希望自己愚昧的看法會影響到了題主。但看到題主補充的那一塊問題說明,有可能也是ctp本身api的數據提取會不會有流量限制。希望能幫到題主。兩種情況 一 你線程死鎖 二 你策略處理數據時間過長
肯定是你策略裡面某個地方阻塞了(死循環或者死鎖) 任何API的問題可以問我
減少策略邏輯的運算耗時才能解決你的實質問題。放到另外線程只會掩蓋問題。
你先把策略屏蔽掉再觀察行情數據是否正常。基本上可以肯定是你代碼的問題。
推薦閱讀:
※Qt 重繪問題?
※如何評價基於 C++ 17 的框架 MCF?
※protobuf 變長64位無符號整數 為什麼最多需要消耗10位元組而不是9位元組?
※C++ 為什麼 Lambda 的引用捕獲 const 變數會失敗?
※C++ type_traits里哪些東西通過標準語言沒有可能實現而必須尋求編譯器內建支持?