簡體   English   中英

Python-C api並發問題

[英]Python-C api concurrency issue

我們正在開發一個小型c服務器應用程序 服務器應用程序執行一些數據處理並響應客戶端。 為了保持數據處理部分的可配置性和靈活性,我們決定使用腳本,並根據各種現成模塊的可用性,我們決定使用Python。 我們使用Python-C api在c和python之間發送/接收數據。

算法的工作原理如下: -

  1. 服務器從客戶端接收一些數據,這些數據存儲在c中創建的字典中。 使用api函數PyDict_New()創建字典; 來自c。 使用api函數PyDict_SetItemString()將輸入存儲為字典中的鍵值對;
  2. 接下來,我們執行python腳本PyRun_SimpleString(); 將腳本作為參數傳遞。 該腳本使用c中創建的字典。 請注意,我們使用PyImport_AddModule()方法創建在c中創建的字典,腳本可以訪問該字典; 和PyModule_AddObject();
  3. 我們將腳本中的數據處理結果作為鍵值對存儲在上面創建的相同字典中。 然后,c代碼可以在腳本執行后簡單地訪問結果變量(鍵值對)。

這個問題我們面臨的問題是,從不同的客戶端進來的並發請求的情況下。 當多個請求來自不同的客戶端時,我們傾向於對象引用計數異常。 請注意,對於為用戶提供的每個請求,我們僅為該用戶創建一個獨立的字典。 為了克服這個問題,我們包含了對PyRun_SimpleString()的調用; 在PyEval_AcquireLock()中; 和PyEval_ReleaseLock();,但這樣做導致腳本執行是一個阻塞調用。 因此,如果腳本需要很長時間才能執行,那么所有其他用戶也在等待響應。

能否請您提出最好的方法,或指出我們哪里出錯了。 請告訴我更多信息。

任何幫助/指導將不勝感激。

也許你錯過了這個答案中提到的一個電話。

你應該閱讀http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock你的問題在第一段中解釋了。

獲取GIL時,請直接操作Python對象。 對PyRun_SimpleString的調用將在內部處理GIL並將在長時間運行的操作或每個X指令上放棄它。 但是,它不是真正的多線程。

編輯:

您需要獲取鎖定,並且需要確保Python知道它處於不同的線程狀態:

// acquire the lock and switch thread state
PyEval_AcquireLock();
PyThreadState_Swap(perThreadState);

// execute some python code
PyEval_SimpleString("print 123");

// clear the thread state and release the lock
PyThreadState_Swap(NULL);
PyEval_ReleaseLock();

我建議你研究multiprocessing模塊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM