Форум сайта python.su
Это как раз и называется GIL (Global Interpreter Lock).
Смотрим sys.getcheckinterval(). По умолчанию - 100.
Это значит вот что:
* Питон захватывает lock
* исполняет 100 инструкций байткода
* отпускает lock
* здесь может произойти переключение потока для многопоточной программы. А может и не произойти.
* захватывает опять - и пошли сначала.
Однопоточная программа тоже постоянно захватывает/отпускает lock - это не отключается.
Такое - для каждого потока. Т.е. если один работает - второй ждет. Т.к. одномоментно поток выполняется только на одном проце - то на четырехядерной машине увидим примерно по 25% на ядро.
Я достаточно полно объяснил?
Офлайн
Андрей Светлов(в нашем случае тест однопоточный, а переключения есть, и не на 100 инструкций, а на милион (целых 16 мс). )
Это как раз и называется GIL (Global Interpreter Lock).
* здесь может произойти переключение потока для многопоточной программы. А может и не произойти.
Офлайн
Эээ.
Повторяю. Специально для танкистов.
Каждые 100 инструкций байткода (внимание, не ассемблера, питон исполняет свой байткод интерпретатором!) происходит следующее:
- отпустили GIL
- захватили GIL
и это делается даже в однопоточном приложении.
#ifdef WITH_THREAD
if (interpreter_lock) {
/* Give another thread a chance */
if (PyThreadState_Swap(NULL) != tstate)
Py_FatalError("ceval: tstate mix-up");
PyThread_release_lock(interpreter_lock);
/* Other threads may run now */
PyThread_acquire_lock(interpreter_lock, 1);
if (PyThreadState_Swap(tstate) != NULL)
Py_FatalError("ceval: orphan tstate");
/* Check for thread interrupts */
if (tstate->async_exc != NULL) {
x = tstate->async_exc;
tstate->async_exc = NULL;
PyErr_SetNone(x);
Py_DECREF(x);
why = WHY_EXCEPTION;
goto on_error;
}
}
#endif
Офлайн
Андрей Светловпотоки в нем будут работать? хочу сам разруливать проблему общих ресурсов
- Питон без GIL - это компиляция без флага WITH_THREAD, который ставится по умолчанию.
Офлайн
Нет, не будут. Тут уж что-то одно.
Мы говорим о программировании на “чистом” питоне - без всяких C embedded?
Тогда как вы будете разруливать из Питона его же интерпретатор? Ведь общие ресурсы как раз в нем, в самых что ни на есть недрах.
Офлайн
Андрей Светловесть же мютексы, семафоры или что-то типа того…
Нет, не будут. Тут уж что-то одно.
Мы говорим о программировании на “чистом” питоне - без всяких C embedded?
Тогда как вы будете разруливать из Питона его же интерпретатор? Ведь общие ресурсы как раз в нем, в самых что ни на есть недрах.
Офлайн
Есть. Но GIL нужен для того, чтобы работал сам Python.
Объекты синхронизации из threading помогут вам в организации мультипоточной работы вашего кода.
И бессильны, если интерпретатор сам по себе не поддерживает многопоточнось.
Так вот, GIL - существенная часть этой поддержки. Выкидываете его - получаете простой однопоточный Питон.
Офлайн
а можно сделать так что-б в определенном куске кода GIL переключения не было, типа: gil-off blabla() gil-on ?
Офлайн
:)
Знаете, это примерно как, гммм, гадить против ветра.
Теоретически, если аккуратно исполнять - возможно.
На практике же прийдется виртуозить и при этом - никакого преимущества по сравнению с классическим способом.
Создавайте C Extension, в котором внутри BEGIN_THREADS/END_THREADS делайте все, что нужно. Даже это будет проще, чем возиться с GIL напрямую. И гораздо безопасней.
Отредактировано (Дек. 6, 2009 15:50:58)
Офлайн
Андрей СветловВторой ждет освобождения ресурсов, а не завершения потока, ведь в этом смысл многопоточности. И если есть свободные ядра у проца, то почему на них не запускается новый поток?
Такое - для каждого потока. Т.е. если один работает - второй ждет.
Андрей СветловТ.е. поток на 100% одно ядро не может загрузить?
Т.к. одномоментно поток выполняется только на одном проце - то на четырехядерной машине увидим примерно по 25% на ядро.
Андрей СветловПолучается, что сам интерпретатор однопоточен? если прерывается для проверки потоков на исполнение?
Я достаточно полно объяснил?
Офлайн