Комментарии 18
Собственно вопрос разработчику ядра:
Когда допилите GIL до изоляции на уровне суб-интерпретаторов?
Насчёт GIL — это просто bool, который устанавливается используя блокировку и не мешает многопоточно выполнять C++ коду в отдельном потоке.
Когда допилите GIL до изоляции на уровне суб-интерпретаторов?
Насчёт GIL — это просто bool, который устанавливается используя блокировку и не мешает многопоточно выполнять C++ коду в отдельном потоке.
+2
Полагаю, к версии 4.0
bugs.python.org/issue15751 если будет сделан поможет написать работу с субинтерпретаторами правильно (PyGILState_Ensure умеет жить только с главным интерпретатором если что).
Основная беда следующая: субинтерпретаторы разделяют слишком много данных. Если питоновский код еще можно как-то развести по углам, то с C Extensions полная беда.
По сложившейся практике данные модуля все хранят как static variables. Существует PEP 3121 для module state, но пока его никто не реализовывает (благо что необязательный).
bugs.python.org/issue15751 если будет сделан поможет написать работу с субинтерпретаторами правильно (PyGILState_Ensure умеет жить только с главным интерпретатором если что).
Основная беда следующая: субинтерпретаторы разделяют слишком много данных. Если питоновский код еще можно как-то развести по углам, то с C Extensions полная беда.
По сложившейся практике данные модуля все хранят как static variables. Существует PEP 3121 для module state, но пока его никто не реализовывает (благо что необязательный).
+1
Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS позволяют параллельное выполнение даже в питоновских потоках.
И, естественно, ничто не мешает создавать отдельные потоки, о которых Питон ничего не знает.
Только Python API без GIL вызывать нельзя. Хоть и очень хочется.
К слову, PyGILState_Ensure/PyGILState_Release — довольно дорогая операция.
Лучше делать её один раз на поток, используя PyEval_SaveThread/PyEval_RestoreThread для временного отпускания GIL.
И, естественно, ничто не мешает создавать отдельные потоки, о которых Питон ничего не знает.
Только Python API без GIL вызывать нельзя. Хоть и очень хочется.
К слову, PyGILState_Ensure/PyGILState_Release — довольно дорогая операция.
Лучше делать её один раз на поток, используя PyEval_SaveThread/PyEval_RestoreThread для временного отпускания GIL.
0
Можно ли объявить эти static variables как threadlocal? Будет ли в этом случае работать описанная выше схема?
+1
Субинтерпретаторы не обязаны работать в разных потоках. Т.е. должна поддерживаться в том числе и схема, при которой несколько субинтерпретаторов разделяют один поток. threadlocal здесь не помогут.
0
Я так понимаю, что в этом случае с собой надо всегда носить контекст, а для этого нужно перелопатить кучу кода как CPython, так и его модулей.
PEP-3121, упомянутый Вами, это и предлагает.
PEP-3121, упомянутый Вами, это и предлагает.
0
На multiprocessing можно реализовать практически любые вещи, которые делаются, например, в java при помощи «нормальных» тредов. Может написать пару статтей, как обмениваться данными между питоническими процессами, делать их синхронными и асинхронными, делать процессы-слушатели и т.п.?
+1
А разве есть какие-то хитрые питонические способы обмена данными между процессами, кроме как средствами ОС?
(а значит, со всяческими сериализациями)
(а значит, со всяческими сериализациями)
0
Конечно есть. Например можно делать общее пространство имён между процессами:
import multiprocessing
def producer(ns, event):
ns.value = 'This is the value'
event.set()
def consumer(ns, event):
try:
value = ns.value
except Exception, err:
print 'Before event, consumer got:', str(err)
event.wait()
print 'After event, consumer got:', ns.value
if __name__ == '__main__':
mgr = multiprocessing.Manager()
namespace = mgr.Namespace()
event = multiprocessing.Event()
p = multiprocessing.Process(target=producer, args=(namespace, event))
c = multiprocessing.Process(target=consumer, args=(namespace, event))
c.start()
p.start()
c.join()
p.join()
+2
В multiprocessing очень много всего.
Мне, например, нравится работа через Pipe для передачи комплексных переменных между процессами.
Мне, например, нравится работа через Pipe для передачи комплексных переменных между процессами.
0
Фактически все нетривиальные (не int, float, str) типы используют сериализацию. Т.к. picke обычно замечательно работает для multiprocessing «из коробки» — никаких неудобств это не доставляет и происходит незаметно для программиста.
+2
Подскажите, когда планировщик забирает у питоноского потока слайс через 5 миллисекунд — он это может сделать в любом месте? Например, если у меня есть франмент кода на питоне:
Поток может быть остановлен после того как элемент изъят из конца списка но до того, как он добавлен в начало списка? Есть какие-то ограничения на то, когда поток можно останавливать — или в абсолютно любое время, так же как в операционных системах?
somelist.insert( 0, somelist.pop() )
Поток может быть остановлен после того как элемент изъят из конца списка но до того, как он добавлен в начало списка? Есть какие-то ограничения на то, когда поток можно останавливать — или в абсолютно любое время, так же как в операционных системах?
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Еще раз о многопоточности и Python