Как стать автором
Обновить

Комментарии 38

Несколько раз в статье забрасывается крючок. Ожидаешь: вот-вот доберусь до сути. И на тебе… На самом интересном. Жду не дождусь продолжения! Спасибо.
Если сильно прямо свербит, почитайте вторую часть в оригинале www.jstorimer.com/blogs/workingwithcode/8100871-nobody-understands-the-gil-part-2-implementation. В комментариях к этим статьям указаны ошибки автора в поверхностном понимании некоторых вещей, советую читать их тоже.
Спасибо! Интересно, как там в других языках всё устроено.
Этот механизм во-первых реализован только в MRI, который хоть и основной интерпритатор в мире Руби, но далеко не единственный. Все остальные имплементации, например jRuby или рубиниус лишены недостатков GIL. Во-вторых, реализация GIL может изменится либо исчезнуть совсем в более поздних версиях MRI, поэтому лучше не полагаться на нее вообще, явно используя примитивы синхронизации, иммутабельные типы и т.п.
например jRuby или рубиниус лишены недостатков GIL

И достоинств GIL они лишены в той же степени…
Мне кажется, что единственное преимущество GIL — упрощение работы для разработчиков интерпритатора. Честно говоря, с точки зрения прикладного программиста на языке, наличие в нем GIL довольно сомнительное преимущество.

Вот простой пример кода, который сводит на нет все мнимые бенефиты от GIL:

@foo = true

def one
  p 'Boo!' if @foo
  @foo = false
end

5.times.map do
  Thread.new do
    one
  end
end.each(&:join)
GIL — это упрощение работы для программиста. Каждой задаче свой инструмент. Нет достоинств без недостатков. Вопрос лишь как вы этим пользуетесь. Дождитесь продолжения или прочитайте оригинал статьи.

Приведенный вами код не рабочий… Я что-то не припомню, чтобы Array#each принимал какие-нибудь параметры…
Да, работает… А что с этим кодом по вашему не так?
С кодом все замечательно, он демонстрирует то, что GIL не спасает от проблем синхронизации в коде приложения: строка вроде бы как должна напечататься один раз, а печатается несколько.
По мне так этот код демонстрирует, что не стоит кому попало заниматься многопоточным программированием.
Вы, например, можете аргументировано обосновать почему этот код должен выводить одну строку?

Когда я писал, что код не рабочий я помимо Array#each имел ввиду и то, что этот, с позволения сказать, код не выдаст детерминированный результат и соответственно абсолютно бесполезен. Даже в качестве генератора случайных чисел.

Ребята, держитесь подальше от многопоточного программирования с такой подготовкой. Даже GIL не способен избавить от необходимости программисту иметь мозги…
Не понимаю вашей аргументации, уж извините. На то, что код рабочий вам указали выше. Я привел вам классический пример рассинхронизации данных между потоками, которому плевать на GIL. Откройте любую книжку по C++ или, к примеру, по Java на разделе «многопоточность» и вы увидите такой же код перед объяснением концепций мьютексов, synchronized секций etc.

Ко всему вышесказанному, наличине GIL в интерпретаторе серьезно замедляет многопоточные приложения на многопроцессорных системах, отбирая у программистов возможность распоряжаться всеми ядрами, толкая их к парадигме запуска n-нного количества программ на n-ядрах, вместо запуска одной.

Вы показали некоторую неосведомленность в знании основ языка, при этом не явили публике ваших аргументов в поддержку GIL. Оставив в стороне ваши необоснованные обвинения, не могли бы вы рассказать, какие же преимущества, по вашему, дает этот механизм прикладному программисту?
Давайте отделим мух от котлет. Код типа вашего приводится в качестве того, как не надо писать многопоточные приложения. Ипользование мютексов при работе с shared memory и семафоров в многопоточном программировании — это идиомы. Вне зависимости от языка.

Не понимаю почему вы решили, что GIL просто обязан ваш по всем канонам кривой код превратить в правильный код. Ни вы, ни ваш товарищ alno не можете сказать, как должен работать этот код. И это правильно, спецификация языка этого не определяет.
Считать корректными выводы, используя некорректные начальные данные (в данном случае некорректный код) даже с точки зрения формальной логики нонсенс.

Метод Symbol#to_proc — это не основы языка, а новая фича языка 1.9. Я избегаю подобные конструкции, поскольку иногда приходится поддерживать код написанный под 1.8.

Конструкция конечно выглядит понтово, но очень неочевидна. Новичок или человек не очень хорошо знакомый с руби эту конструкцию с ходу не поймет. Найти это в документации, не зная что ищешь, невозможно. Говорят, среди продвинутых неочевидный код считается дурным тоном…

Плюс у нее очень узкое применение (работает только с методами, которые принимают один-единственный параметр, если я правильно понимаю).

Как говаривает в таких случаях один товарищ в наших краях: грёбанная магия, долбанное волшебство…

Про преимущества будет в конце второй части этой статьи. Вам нравится когда вам пересказывают фильм, на который вы только что купили билет?
Метод Symbol#to_proc — это не основы языка, а новая фича языка 1.9. Я избегаю подобные конструкции, поскольку иногда приходится поддерживать код написанный под 1.8.

ruby-doc.org/core-1.8.7/Symbol.html#method-i-to_proc
Давайте отделим мух от котлет

Давайте! Для начала перечитайте внимательно мой первый комментарий в этом треде, с которым вы стали спорить.

Ни alno ни я ничего не решал, ни по поводу оценки работоспособности кода, который я вам привел (с чисто философской стороны этот код выдает предсказуемый результат, если знать все исходные, но практически его поведение неопределенное и непредсказуемое). Более того, никто из нас не решал, что GIL что-то обязан прикладному программисту, это ваше утверждение, что он имеет какие-то преимущества для программиста, и мы ждали (и все еще ждем) от вас подобных примеров, что бы найти хоть какое-то полезное применение этой технологии на практике.

Symbol#to_proc имеет более существенные недостатки, чем ухудшение читабельности, и я согласен с тем, что подобные конструкции не стоит писать в production-ready коде, но это не повод воинственно утверждать, что код, который вы даже не потрудились проверить — нерабочий. Отмечу, что я переработал кусок кода из статьи, который написан в таком же стиле, вы уверены, что внимательно читали ее?

Вам нравится когда вам пересказывают фильм, на который вы только что купили билет?

При чем тут спойлеры, эти знания обязательные для любого человека, называющего себя разработчиком на языке Руби. К слову, я читал все три части еще в оригинале и не нашел ничего нового для себя, а вы, судя по всему не читали, иначе бы не пропустили выводы автора, с которыми я и не спорил.

Итак, повторю свой вопрос, какие такие замечательные возможности дает вам GIL, что перекрывает для вас его объективно значительные недостатки?
Это какие же недостатки он (#to_proc) имеет? Всегда использовал его и горя не знал. С точки зрения читабельности, на мой взгляд, &method намного удобнее, чем {|name| name.method} для человека, который знает, как это работает.

А если все время подстраиваться под новичков, как предлагает northbear, то может нам вообще стоит остаться в каменном веке? А 1.8 ветка, насколько я помню, уже не поддерживается, да и код там этот поддерживается.
Раньше были проблемы с выделением памяти, насколько я помню (еще в те времена, когда этот метод был рельсовый), и с увеличением времени на вызов методов (в 2-3 раза). Проверил на MRI 2.0.0p247, никаких ликов нет, время на вызов соизмеримое. По поводу вкусов спорить не буду, лично мне версия без &: нравится намного больше.
Переводчик будет рад услышать замечания и конструктивную критику.


Вы проделали большой объем работы, текст читается легко, спасибо! Когда будете переводить 2ю часть, пожалуйста переведите и комментарии, там много полезных исправлений.
GIL на то и GIL чтобы блокировать, без транзакционной памяти этот вопрос не обойти
Вообще-то, обойти — см. BEAM. Вкратце — своя куча и свой GC у каждого потока. У этого подхода есть свои минусы, однако, эффект потрясающий.
Чем это проще и лучше форка с SHM?
Полагаю, STM несколько сложнее в реализации. Черт его знает, на самом деле.
Алсо, не смог найти актуальной информации по теме. Этот форк вообще существует?
В PyPy реализация софтверная есть, хардкор пока от Интелов ждут.
Про форк с SHM я имел ввиду process shared memory
Кто такой «BEAM» и где про него надо смотреть?
Erlang VM. Вкратце ознакомиться можно в habrahabr.ru/post/117538/
Извините, но Эрланг изначально спроектирован так, что в нем все операции thread-safe.

Возьмём пример из статьи. В Эрланге нет аналога операции array << nil. В Эрланге вы можете создать переменную и присвоить ей значение, но изменить её после этого вы не можете.

Без должной подготовки и навыков писать на эрланге очень тяжело. Но параллельность — это да…
Руби в плане программирования полная противоположность Эрлангу. Но GIL…

Так устроен мир. За всё нужно платить. Как это вообще можно сравнивать, я не понимаю…
Вообще, изначально было постулировано, что только STM спасет мир. BEAM был контрпримером. Про язык речи вообще не шло.

Кстати, хоть VM и накладывает свой отпечаток, не все так страшно. В эрланге можно иметь shared mutable state, хоть это и будет выглядеть весьма отлично от других языков. Кстати, где это будет дороже по производительности — тоже под вопросом. В конце концов, никто не запрещает разработать другой язык под BEAM, где будут изменяемые переменные и array
Кем и что «изначально было постулировано»? Мы вроде тут обсуждаем статью про GIL в MRI, конкретной реализации ruby.

Архитектура виртуальной машины Elrang'а очень хорошо адаптирована под структуру и концепцию языка и поэтому очень эффективна. Но утверждать, что раз она эффективна для Erlang'а, то значит она будет столь же эффективна для ruby, как минимум странно…

В конце концов, никто не запрещает разработать другой язык под BEAM, где будут изменяемые переменные и array

Как у вас всё легко. Вас послушать, так и вы и корову запросто летать научите…
GIL на то и GIL чтобы блокировать, без транзакционной памяти этот вопрос не обойти

Это изначальный постулат.
В конце концов, никто не запрещает разработать другой язык под BEAM, где будут изменяемые переменные и array

Такой язык уже есть, elixir.
GIL на то и GIL чтобы блокировать, без транзакционной памяти этот вопрос не обойти

Это изначальный постулат.

Вы знаете, что такое atoms и зачем нужна atoms tables в BEAM? Что происходит когда два потока пытаются обратиться к одному атому в BEAM? Вы будете сильно удивлены, но один из потоков будет блокирован…

Транзакционность памяти тут вообще не причем, это автор того сообщения сумничал не к месту.

Такой язык уже есть, elixir.

Попробуйте написать на elexir'е код, разбираемый в статье, и сравните результаты. BEAM — это принципиально другая концепция, которая имеет куда более серьезные ограничения чем GIL в MRI… Но именно благодаря этому BEAM в определенных применениях очень силён. Нет достоинств без недостатков…
Да тут вроде разговор, что не GIL'ом единым и транзакционной памятью можно решить проблему многопоточности в приложениях. Как пример – BEAM.
А elixir тут как пример альтернативного языка для BEAM.
К слову, на Руби есть попытки реализации модели акторов и некоторых других эрланговских подходов: github.com/celluloid/celluloid. Не хочу давать какую-то оценку этому фреймворку, просто отмечаю сам факт его наличия.
>> Как у вас всё легко.
Ну так. Люди под х86 компиляторы пишут, и ничего. А тут все же VM.
A programmer had a problem. He thought to himself, «I know, I'll solve it with threads!». has Now problems. two he
Была у программиста проблема: найти по шаблону подстроку в строке. Решил использовать для этого регэкс. Теперь у него две проблемы…
Так всегда: хочешь побыстрее долететь — потрать чуток лишнего времени на изготовку.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории