Информация об изменениях

Сообщение Re[19]: Почему Эрланг от 15.06.2015 7:42

Изменено 15.06.2015 10:33 Pauel

Здравствуйте, vdimas, Вы писали:

V>Ну и еще в Windows 16 работали перывания прямо в юзверском коде ))

V>Поэтому, если твоя прога сидела на прерываниях, то эти прерывания тоже как-то обыгрывались: либо ресурсы защищались теми же критическими секциями, либо для какого-то участка кода запрещались прерывания.

Ты наверное с ДОС попутал. В Win16, по моему, прикладной код не имеет доступа к прерываниям.

I>>Как так, ведь в кооперативной многозадачности "гонок нет"


V>В Windows 16 (если ты о ней) кооперативный шедулер срабатывал на КАЖДЫЙ вызов системного АПИ, наверно в этом дело?


Это не важно.

V>Т.е., ты пытаешься сравнить ситуацию, когда ты вручную расставляешь точки переключений задач с ситуацией, когда у тебя эти точки переключения задач расставлены даже в тех местах, где ты бы НЕ ХОТЕЛ, чтобы переключение произошло.


Переключение делается само, внутри нода того же. Все что мне надо — связывать.

V>В базе жабаскрипта есть вполне детерминированная однопоточная модель вычислений — ты можешь пользоваться знаниями об этом.


Этого недостаточно, что бы все программы обладали детерминированым поведением. Время, например, никуда не девается.

V>Но в жабаскрипте для обеспечения детерминированности достаточно, чтобы м/у точками (1) и (2) не произошло переключения задач. Т.е. не вставляй м/у точками (1) и (2) никаких await/yield и всех делов.


И наверное ты посоветуешь использовать синхронное АПИ нода, а когда не хватит производительности — перейти на С++, а заказчику сказать, что уже решенная задача на самом деле не стоит того, что бы над ней работать ?

V>Если же ты м/у этими точками вставляешь инструкции переключения потоков, то твоя недетерминированность создана искусственно, т.е. является эмуляцией недетерминированности с помощью детерминированного инструмента.


Ты хорошо понимаешь, что node это асинхронный апи ?

I>>У тебя плохой пример. Раздели чтение переменной и запись на две операции. Внезапно, обнаруживаем инвариант — поток затирает ровно то значение, которое перед этим прочёл.


V>Да, но где здесь недетерминированность?


Доступ к ресурсу определяется не твоим кодом, а внешним фактором — временем и другими участками кода, которые, к слову, никакого отношения к твоей задаче не имеют.

V>Теперь другой пример:

V>
V>}
V>


Ты привел тот же пример, что и я, только нерабочий. Давно у тебя такое ?

V>Пример тоже полностью детерминированный. Ты можешь полагаться на значение локальной переменной x1, но уже не можешь полагаться на значение x после ручного переключения потоков на await.


Пример детерминированый, но полагаться нельзя
Детерминированый, это когда можно точно сказать, что на что изменится и в каком случае.

I>>Если компилятор не гарантирует атомарность инкремента

V>Компилятор ничего не может гарантировать. Он просто использует низлежащую модель вычислений.

Если хочешь поговорить про это создай новый тред.

V>Слава те хосподя, об этом и пример ))


Посмотри внимательно — я про это и говорю что два года назад, что сейчас.

I>>И именно эта последовательность ломает состояние. То есть, гонки налицо. Видишь их?


V>Для случая С++? Конечно, это же был мой пример.


I>>Теперь твой пример на JS, вместо потока — задача. Что читаем i и записываем отдельно.

I>>Запускаем один таск — никаких нарушений инварианта нет, всё шоколадно.
I>>Запускаем второй таск, опаньки — инвариант ломается.

V>Ну он же не сам поломался, это ты специально, ручками, сделал так, чтобы переменные i и actual изменялись/проверялись в РАЗНЫХ циклах запуска жабаскрипта. А ты сделай так, чтобы эти переменные изменялись в рамках одного цикла запуска скрипта и всё будет ОК.


Пример доказывает существование проблемы которую ты отрицал два года Как переписать — абсолютно не важно.

I>>Здесь, внимание, порядок выполнения зависит исключительно от того, в какой момент стартовал новый таск.


V>Да похер, сорри.


Это не так. Если правильно угадать время, инвариант ломаться не будет. Можешь поэкспериментировать, выбери задержки побольше и всё.

V>Ты НЕ можешь полагаться на значение переменных, оставшихся с прошлого запуска, потому что тебе недоступна история этих прошлых хапусков, не предоставляет жабаскрипт такой инфы, ты можешь полагаться на значения переменных, прочитанных в рамках текущего запуска.


Ну вот, ты узнал, откуда в асинхронном коде недетерминизм
1. время
2. история
3. глубина ветвления
4. количество прерываний по каждой ветке зависит от 1.2.3

V>Ты вообще смотрел мой пример? Не обратил внимание на такой момент:


Они абсолютно идентичны. Ну разве что ты в каждом примере хочешь показать всё сразу, на все возможные темы.

V>Если бы мне


Это уже неинтересно. Важно, что ты понял откуда берется недетерминизм.

V>И ты, именно ты, как программист, должен ЗНАТЬ низлежащую вычислительную модель.


Ну вот сегодня ты наконец узнал, откуда берется недетерминизм.

I>>И если два потока пишут в один файл, не важно, логических или физических, результат может быть недерминирован.


V>Ну так открывай файл с исключительным доступом, елки. И не шарь владение хендлом на файл.


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

V>Я пока проблему никак не могу уловить.

V>Не мог бы ты озвучить ТЗ целиком?

Зачем ? я и так знаю что "любой студент за пару часов" @ vdimas

I>>Это, в частности, проявляется в том, что содержимое файла при одном запуске будет "111222" а во втором случае "121212" а в третьем "122211"


V>Ну это согласно ТЗ так или из-за ошибок в коде?


Это за того самого недетерминированого порядка выполнения. Смотри внимательно мой пример.
Re[19]: Почему Эрланг
Здравствуйте, vdimas, Вы писали:

V>Ну и еще в Windows 16 работали перывания прямо в юзверском коде ))

V>Поэтому, если твоя прога сидела на прерываниях, то эти прерывания тоже как-то обыгрывались: либо ресурсы защищались теми же критическими секциями, либо для какого-то участка кода запрещались прерывания.

Ты наверное с ДОС попутал. В Win16, по моему, прикладной код не имеет доступа к прерываниям.

I>>Как так, ведь в кооперативной многозадачности "гонок нет"


V>В Windows 16 (если ты о ней) кооперативный шедулер срабатывал на КАЖДЫЙ вызов системного АПИ, наверно в этом дело?


Это не важно.

V>Т.е., ты пытаешься сравнить ситуацию, когда ты вручную расставляешь точки переключений задач с ситуацией, когда у тебя эти точки переключения задач расставлены даже в тех местах, где ты бы НЕ ХОТЕЛ, чтобы переключение произошло.


Переключение делается само, внутри нода того же. Все что мне надо — связывать.

V>В базе жабаскрипта есть вполне детерминированная однопоточная модель вычислений — ты можешь пользоваться знаниями об этом.


Этого недостаточно, что бы все программы обладали детерминированым поведением. Время, например, никуда не девается.

V>Но в жабаскрипте для обеспечения детерминированности достаточно, чтобы м/у точками (1) и (2) не произошло переключения задач. Т.е. не вставляй м/у точками (1) и (2) никаких await/yield и всех делов.


И наверное ты посоветуешь использовать синхронное АПИ нода, а когда не хватит производительности — перейти на С++, а заказчику сказать, что уже решенная задача на самом деле не стоит того, что бы над ней работать ?

V>Если же ты м/у этими точками вставляешь инструкции переключения потоков, то твоя недетерминированность создана искусственно, т.е. является эмуляцией недетерминированности с помощью детерминированного инструмента.


Весь интересный функционал асинхронный до самого дна. сеть, файловая система, бд и тд. У них своё время, не такое как у VM джаваскрипта. То есть, уже просто http.get вносит неопределенность, потому что это внешний, то есть, time-bound фактор. Любой функционал OS, база данны — ровно то же.
В этом плане правильно эмулировать IO не через setTimeout(fn, 1000) а вот так setTimeout(fn, Math.random(10*1000))

I>>У тебя плохой пример. Раздели чтение переменной и запись на две операции. Внезапно, обнаруживаем инвариант — поток затирает ровно то значение, которое перед этим прочёл.


V>Да, но где здесь недетерминированность?


http.get, filesystem.readFile, database.execute. Нет и никогда не будет функционала навроде "в какое место очереди эвентлупа вставить колбек респонса http.get"

V>Пример тоже полностью детерминированный. Ты можешь полагаться на значение локальной переменной x1, но уже не можешь полагаться на значение x после ручного переключения потоков на await.


Пример детерминированый, но полагаться нельзя
Детерминированый, это когда можно точно сказать, что на что изменится и в каком случае.

V>Слава те хосподя, об этом и пример ))


Посмотри внимательно — я про это и говорю что два года назад, что сейчас.

I>>И именно эта последовательность ломает состояние. То есть, гонки налицо. Видишь их?


V>Для случая С++? Конечно, это же был мой пример.


I>>Теперь твой пример на JS, вместо потока — задача. Что читаем i и записываем отдельно.

I>>Запускаем один таск — никаких нарушений инварианта нет, всё шоколадно.
I>>Запускаем второй таск, опаньки — инвариант ломается.

V>Ну он же не сам поломался, это ты специально, ручками, сделал так, чтобы переменные i и actual изменялись/проверялись в РАЗНЫХ циклах запуска жабаскрипта. А ты сделай так, чтобы эти переменные изменялись в рамках одного цикла запуска скрипта и всё будет ОК.


Пример доказывает существование проблемы которую ты отрицал два года Как переписать — абсолютно не важно.

I>>Здесь, внимание, порядок выполнения зависит исключительно от того, в какой момент стартовал новый таск.


V>Да похер, сорри.


Это не так. Если правильно угадать время, инвариант ломаться не будет. Можешь поэкспериментировать, выбери задержки побольше и всё.

V>Ты НЕ можешь полагаться на значение переменных, оставшихся с прошлого запуска, потому что тебе недоступна история этих прошлых хапусков, не предоставляет жабаскрипт такой инфы, ты можешь полагаться на значения переменных, прочитанных в рамках текущего запуска.


Ну вот, ты узнал, откуда в асинхронном коде недетерминизм
1. время
2. история
3. глубина ветвления
количество прерываний по каждой ветке зависит от 1.2.3

V>Ты вообще смотрел мой пример? Не обратил внимание на такой момент:


Они абсолютно идентичны. Ну разве что ты в каждом примере хочешь показать всё сразу, на все возможные темы.

I>>И если два потока пишут в один файл, не важно, логических или физических, результат может быть недерминирован.


V>Ну так открывай файл с исключительным доступом, елки. И не шарь владение хендлом на файл.


У меня нет никаких хендлов. речь про последовательность транзакций вида "open-append-close"
Каждая такая транзакция нигде не прерывается, но последовательность таких вот транзакций зависит, скажем, от того, какой респонс вернулся первым — от бд или от нетворка.

I>>Это, в частности, проявляется в том, что содержимое файла при одном запуске будет "111222" а во втором случае "121212" а в третьем "122211"


V>Ну это согласно ТЗ так или из-за ошибок в коде?


Это за того самого недетерминированого порядка выполнения. Смотри внимательно мой пример.