Pull to refresh
90
0
Дмитрий @blinky-z

User

Send message

Все запутанно)
Но главное, чтобы все понимали о чем идет речь. Например, многие говорят "функционал" вместо "функциональность" (приложения), но все равно всем понятно о чем идет речь из контекста.

Не 0, а 1. И далее во всем абзаце.

Нет, я говорю именно про ситуацию, когда читаем 0. Давайте посмотрим еще раз на пример:

    private int x;
    private int y;

    public void T1() {
        x = 1; // W1
        int r1 = y; // R1
    }

    public void T2() {
        y = 1; // W2
        int r2 = x; // R2
    }

Если мы прочитали на R1 любое значение (хоть 0, хоть 1, но нас интересует именно 0), то запись W1 точно произошла, а значит на чтении R2 мы должны будем увидеть 1. Аналогично рассуждаем и о втором треде. Таким образом, мы можем увидеть 0 только на одном из чтений, но никак не на обоих, так как это просто невозможно если смотреть с точки зрения порядка в программе, ведь хотя бы одна запись должна была произойти.
Другими словами, выполнение программы начинается или с записи x, или с записи y. Если мы прочитали (0, 0), то это означало бы, что выполнение программы началось с чтений, но ведь они идут после записей? Однако это происходит по причине memory reordering, так как Java не дает sequential consistency по умолчанию.

Не LoadStore, а StoreLoad.

Нет, это называется именно LoadStore (читать так: loads can be reordered after stores).

Не StoreLoad, а LoadStore.

И здесь тоже именно StoreLoad (читать так: stores can be reordered after loads). Кстати, причина наличия такого переупорядочивания в x86 - это Store Buffer.

Да, это про implementation и consistency. Лично я придерживаюсь мнения, что говорить "имплементация" - наоборот корректнее, чем "реализация". Та же вики под Реализацией имеет в виду что-то другому, чем Имплементация. Не знаю, насколько валидно говорить "консистентность" (наверное правильнее "согласованность"?), но это понятие используется повсеместно и если всем все понятно, то проблемы нет :)

Насчет перевода в Exclusive состояние еще уточню, но кажется вы правы, спасибо!

Но ведь данные чтения никак не аффектят друг друга, а поэтому их можно переупорядочить :) Перечитайте раздел [Happens-Before] Same thread actions - там написано о том, как переупорядочивание действий в треде не нарушает happens-before.
Только в том случае, если связать с помощью happens-before действия в разных тредах, happens-before будет гарантировать, что инструкция чтения R2 произойдет только после R1 (запретит LoadLoad memory reordering), а инструкция записи W1 произойдет до W2 (запретит StoreStore memory reordering), иначе happens-before в цепочке действий (W1,W2,R1,R2) было бы нарушено.
Другими словами, пока мы не свяжем W2 и R1 с помощью happens-before (что дает нам volatile), то не будет happens-before между наборами действий (W1,W2) и (R1,R2).

Кстати, вот яркий пример. Взгляните на данный тест - https://github.com/blinky-z/JmmArticleHabr/blob/main/jcstress/tests/object/JmmReorderingObjectTest.java. Суть его в том, что мы можем прочитать неконсистентное состояние объекта, даже если увидели non-null ссылку. Он воспроизводится на ARM, но совсем не воспроизводится на x86, т.к. последний запрещает StoreStore/LoadLoad reordering.

Кстати, вот яркий пример. Взгляните на данный тест - https://github.com/blinky-z/JmmArticleHabr/blob/main/jcstress/tests/object/JmmReorderingObjectTest.java. Суть его в том, что мы можем прочитать неконсистентное состояние объекта, даже если увидели non-null ссылку. Он воспроизводится на ARM, но совсем не воспроизводится на x86, т.к. последний запрещает StoreStore/LoadLoad reordering.

Укажите, пожалуйста, на ошибки. Буду только рад поправить и сделать материал лучше

Вы абсолютно правы, x86 обладает намного более строгими гарантиями по сравнению с ARM/Power. Об этом я также упоминал несколько раз в статье

Asciidoc, к сожалению, не так лаконичен, прост и читабелен как Markdown. Например, об этом сказано даже в спеке CommonMark

Вы полностью правы.

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

Писал статью сам. В статье хотел поделиться опытом работы и показать внутреннюю кухню, что было бы полезно тем кто еще на старте карьеры и рассматривает в качестве работы крупные компании или хотел бы работать в нашей компании, но не знает, как тут у нас все устроено. Наверное статья кажется не такой живой, потому что в основном я рассказываю об устройстве компании и выстроенных процессах, чем конкретно о себе)

Рекомендую st для более глубого изучения устройства терминалов — это точно самый простой и понятной терминал на сегодня. https://st.suckless.org/

Хотя насчет простоты xterm я все таки погорячился — его соурс код сложно понятен, да и вообще сам он раздут сильно по возможностям и наполнен многими ненужными в актуальное время вещами. Но в качестве понимания того, как примерно эмулятор терминала работает, вполне пойдет

Посмотрел.


  1. /dev/ptmx — это все таки устройство. Фраза — "это не устройство, а интерфейс" странная, так как данное и является интерфейсом для создания pty. Как это работает? Мы вызываем open(/dev/ptmx), и вызов open обслуживает драйвер данного устройства, конкретнее мы видели, что за это отвечает функция ptmx_open.
  2. "PTM и PTS — это виртуальные устройства...". Да, это верно, но не по той причине что вы написали, а потому, что они не существуют физически на диске, а живут в виртуальной файловой системе /dev, т.е. живут в памяти, в ядре. Вообще, то, как я определил виртуальные устройства — расходится с тем, что говорит википедия. Там виртуальные устройства — это устройства, не взаимодействующие напрямую с аппаратными устройствами. Так что лучше избегать понятия "виртуальное устройство" по отношению к ptm/pts и говорить, что PTM и PTS являются файлами устройств, а конкретнее, терминальными устройствами. Не думаю, что их можно назвать виртуальными устройствами, так как формально они взаимодействуют с терминалом. Вот /dev/null уже является виртуальным устройством.
  3. Ну и последнее я считаю своей самой большой ошибкой в статье. Зря я вообще заикнулся о gnome терминале. Дело в том, что его работа намного сложнее, чем какой-нибудь xterm. Он не создает новые процессы для терминалов, а запускает их внутри тредов. Программы внутри терминала конечно же запускаются в отдельных процессах (а конкретнее этим занимается vte widget и его функция vte_terminal_spawn_async). Мой вам совет — поизучайте xterm — крайне простой и понятный эмулятор терминала, который, более того, работает в обход gtk, gnome и всяких других графических тулкитов.
    Если вам интересно, убедиться в том, что gnome терминал — не отдельный процесс, можно достаточно просто. Введите:
    $ ps --pid $$ --format ppid=

И вы увидите, что родителем баша является сам Gnome Terminal Server. Да, это кажется странным со стороны, но наверняка на то были причины, что gnome терминалы работают внутри тредов. Первую причину, которую я вижу, это функциональность вкладок (tabs).


Пишите в лс, можем еще что-то обсудить, если понятнее не стало :)

Хотел поставить плюс за ваш комментарий, приятно видеть разбирающихся людей в такой узкой сфере. Но я случайно промахнулся по кнопке голоса, так что апну этот комментарий)

xfce4-terminal работает в одном процессе, а gnome-terminal — в двух (сервер и клиент)

Разве gnome не запускает терминалы в тредах внутри сервера?

Да, конечно же спавнится новый процесс и уже в нем запускается Shell. Смотрите эту функцию: https://developer.gnome.org/vte/unstable/VteTerminal.html#vte-terminal-spawn-async. Это — VTE widget, созданный и поддерживаемый GNOME. В нем и происходит почти вся работа по созданию терминалов. Конкретно в данной функции 4 аргументом принимается нужная команда, создается PTY и в новом процессе запускается данная команда на созданном PTY.

Замечу одну неточность в вашем ответе:


Вы сказали, что связь между pty master и pty slave это аналог линии связи. Однако, ведь это не правда. Линия связи лежала перед UART устройством. Байты с UART устройства принимал UART драйвер и передавал их после обработки драйверу консоли. Сейчас заместо uart драйвера и драйвера консоли выступают PTM и PTS устройства. Дисциплина линии же все также лежит между этими двумя устройствами, но здесь нет никакой линии связи больше. Конечно, это не отдельная дисциплина линии, а экспортируется дисциплина одного из устройств. Линия связи ушла, но дисциплина линии осталась. Точно также, как и название TTY — очень много концепций сохранилось с тех времен, поэтому не забывайте, что, может быть, хоть и сейчас "дисциплина линии" это что-то непонятное, но если мы окунемся в прошлое, то название будет иметь смысл.

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Date of birth
Registered
Activity