CPython-3.8,https://github.com/python/cpython/blob/v3.8.1/Modules/itertoolsmodule.c#L4129
static PyTypeObject count_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"itertools.count", /* tp_name */
sizeof(countobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)count_dealloc, /* tp_dealloc */
0, /* tp_vectorcall_offset */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_async */
(reprfunc)count_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
itertools_count__doc__, /* tp_doc */
(traverseproc)count_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)count_next, /* tp_iternext */
count_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
itertools_count, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
// ... ... ...
static PyObject *
count_nextlong(countobject *lz)
{
PyObject *long_cnt;
PyObject *stepped_up;
long_cnt = lz->long_cnt;
if (long_cnt == NULL) {
/* Switch to slow_mode */
long_cnt = PyLong_FromSsize_t(PY_SSIZE_T_MAX);
if (long_cnt == NULL)
return NULL;
}
assert(lz->cnt == PY_SSIZE_T_MAX && long_cnt != NULL);
stepped_up = PyNumber_Add(long_cnt, lz->long_step);
if (stepped_up == NULL)
return NULL;
lz->long_cnt = stepped_up;
return long_cnt;
}
static PyObject *
count_next(countobject *lz)
{
if (lz->cnt == PY_SSIZE_T_MAX)
return count_nextlong(lz);
return PyLong_FromSsize_t(lz->cnt++);
}
stepped_up = PyNumber_Add(long_cnt, lz->long_step);
和lz->long_cnt = stepped_up;
之间(或者在PyNumber_Add()
内部)没有地方可以切换线程,所以发生了所谓的“慢模式”。PyLong_FromSsize_t(lz->cnt++)
的构造显然是原子的。当Python字节码运行时,在某些点上会发生线程切换。还有I/O函数。
内存栅用于消除内存重排序副作用。
i++
实际上并不是原子操作,也不是任何函数调用。 - Guy