[英]Python and multithreading
python incref是這樣定義的
#define Py_INCREF(op) ( \
_Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \
((PyObject *)(op))->ob_refcnt++)
對於多核,增量僅是L1高速緩存,不會刷新到內存。
如果兩個線程同時在不同的內核中增加該引用,而沒有刷新到實際內存,那么對我來說,可能會丟失一個增量。 -ob_refcnt = 1-核心1的L1高速緩存中的核心1增量,但不刷新=> ob_refcnt = 2-核心2的L1高速緩存中的核心2增量,但不刷新=> ob_refcnt = 2-WTF
使用多核或多進程有風險嗎?
PyObject的聲明如下:
typedef struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} PyObject
但是Py_ssize_t只是ssize_t或intptr_t。
似乎未使用_Py_atomic *函數和屬性。
Python如何管理這種情況? 如何刷新線程之間的緩存?
Python的CPython實現具有全局解釋器鎖(GIL) 。 調用大多數Python C API函數(包括Py_INCREF
)而不持有此鎖是未定義的行為,幾乎可以肯定會導致數據不一致或程序崩潰。
可以按照文檔中的說明釋放和獲取 GIL。
由於需要持有此鎖才能在Python對象上進行操作,因此Python中的多線程非常有限,並且唯一能夠並行化的操作是諸如在大型數組上等待IO或純C計算之類的事情。 multiprocessing
模塊(啟動隔離的Python進程)是並行Python的另一個選項。
已經嘗試使用原子類型進行引用計數 (以消除/最小化對GIL的需求),但是這些操作導致單線程代碼的顯着減慢,因此被放棄了。
為什么不使用Python的Lock或Semaphore? https://docs.python.org/2/library/threading.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.