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

Сообщение Re[29]: Для тех, кто смеется над JavaScript от 29.06.2020 9:01

Изменено 29.06.2020 9:47 Pauel

Re[29]: Для тех, кто смеется над JavaScript
Здравствуйте, Serginio1, Вы писали:

I>>Следовательно, весь цикл чтение-модификация-запись неатомарны, т.к. во время await управление уходит в эвентлуп, а тот волен передать это управление куда угодно, что у него там в очереди, в т.ч. другой такой же задаче. Windows Phone в 2011-м

S> Это я понимаю. Но если для данного класса выполняется только один метод, то откуда гонки.

Гонки когда разные ЗАДАЧИ обращаются к одному ресурсу одновременно. ЗАДАЧИ, а не только потоки. Любые задачи, любого происхождения.
И гонки надо искать в зависимости от природы многозадачности.
То есть, всего три условия
1 ресурс разделяется между задачами
2 протокол доступа неатомарный с т.з. конкретной многозадачности.
3 параллельное исполнение

I>>Скажем, один экземпляр сделал await read и прочитал 10. Присвоения еще не было, но управление ушло в эвент луп, а в эвентлупе в очереди вызов write другого экземпляра, который пишет 8. Потом возврат в твой экземпляр, завершается await присходит присвоение 10, инкремент 10 -> 11, write и уход в эвентлуп.


S> Угу был вопрос по сути про однозадачность. Там нет гонок.


У тебя многозадачность = однопоточность. поточность это стратегия использоваться процессорного ядра, физическая реализация.
А задачи это логический уровень.

Синхронный код — одна задача на поток. Асинхронный — несколько задач на один и тот же задач, чередуются как попало.

I>>Еще раз — нет, не гарантирует и никогда не гарантировал и никогда не будет. Ты начитался ахинеи про какой то другой язык на другой платформе.

S> Объясни как при выполнении одной задачи могут быть гонки?

Асинхронный однопоточный код это такая вот реализация многозадачности. Соответсвенно,несколько задач работают с одним и тем же ресурсом.

S>Тогда если выполняется обычный синхронный метод и один или множество асинхронный метод то будут гонки.


Разумеется. Асинхронный код дает гонки вне зависимости от числа потоков. Синхронный код дает гонки на нескольких потоках.

I>>Результат выполнения — всегда 10. А должен быть 60. Всегда 10 потому что эвентлуп всегда загружен одинаково, потому предсказуемая работа. Когда будет недетерминизм от IO, таймера и тд, т.е. внешней системы, результат будет прыгать около нуля.


[code]
S>function write_i(value) {
S> iiii = value;
S>}
S>[/cs]
S> тоже не будет атомарности.

Одного только write не хватит, т.к. read по прежнему неатомарный и весь цикл read-increment-write неатомарный.

S>
S>await task(10, 1);
S>await task(10, 2);
S>await task(10, 3);
S>await task(10, 4);
S>await task(10, 5);
S>await task(10, 6);
S>write(10);
S>


S>Никаких гонок не будет.


Снова теоретизирование. Ты запускать пробовал? Почему результат по прежнему 10 когда должен быть 60?

Атомарность будет только в том случае, когда и read и инкремент и write от начала и до конца будут в одном тайм-фрейме.

Этого можно добиться двумя путями

1. переписать полностью на синхронный код, т.е. убрать все await и async. Тогда это гарантируется синхронным однопоточным исполнителем.

2. завернуть read-increment-write в очередь, эдакий асинхронный мутекс. Соответсвенно, снова никто вклиниваться не сможет.
Re[29]: Для тех, кто смеется над JavaScript
Здравствуйте, Serginio1, Вы писали:

I>>Следовательно, весь цикл чтение-модификация-запись неатомарны, т.к. во время await управление уходит в эвентлуп, а тот волен передать это управление куда угодно, что у него там в очереди, в т.ч. другой такой же задаче. Windows Phone в 2011-м

S> Это я понимаю. Но если для данного класса выполняется только один метод, то откуда гонки.

Гонки когда разные ЗАДАЧИ обращаются к одному ресурсу одновременно. ЗАДАЧИ, а не только потоки. Любые задачи, любого происхождения.
И гонки надо искать в зависимости от природы многозадачности.
То есть, всего три условия
1 ресурс разделяется между задачами
2 протокол доступа неатомарный с т.з. конкретной многозадачности.
3 параллельное исполнение

I>>Скажем, один экземпляр сделал await read и прочитал 10. Присвоения еще не было, но управление ушло в эвент луп, а в эвентлупе в очереди вызов write другого экземпляра, который пишет 8. Потом возврат в твой экземпляр, завершается await присходит присвоение 10, инкремент 10 -> 11, write и уход в эвентлуп.


S> Угу был вопрос по сути про однозадачность. Там нет гонок.


У тебя многозадачность = однопоточность. поточность это стратегия использоваться процессорного ядра, физическая реализация.
А задачи это логический уровень.

Синхронный код — одна задача на поток. Асинхронный — несколько задач на один и тот же задач, чередуются как попало.

I>>Еще раз — нет, не гарантирует и никогда не гарантировал и никогда не будет. Ты начитался ахинеи про какой то другой язык на другой платформе.

S> Объясни как при выполнении одной задачи могут быть гонки?

Асинхронный однопоточный код это такая вот реализация многозадачности. Соответсвенно,несколько задач работают с одним и тем же ресурсом.

S>Тогда если выполняется обычный синхронный метод и один или множество асинхронный метод то будут гонки.


Разумеется. Асинхронный код дает гонки вне зависимости от числа потоков. Синхронный код дает гонки на нескольких потоках.

I>>Результат выполнения — всегда 10. А должен быть 60. Всегда 10 потому что эвентлуп всегда загружен одинаково, потому предсказуемая работа. Когда будет недетерминизм от IO, таймера и тд, т.е. внешней системы, результат будет прыгать около нуля.


[code]
S>function write_i(value) {
S> iiii = value;
S>}
S>[/cs]
S> тоже не будет атомарности.

Одного только write не хватит, т.к. read по прежнему неатомарный и весь цикл read-increment-write неатомарный.

S>
S>await task(10, 1);
S>await task(10, 2);
S>await task(10, 3);
S>await task(10, 4);
S>await task(10, 5);
S>await task(10, 6);
S>write(10);
S>


S>Никаких гонок не будет.


Снова теоретизирование. Ты запускать пробовал? Почему результат по прежнему 10 когда должен быть 60?

Атомарность будет только в том случае, когда и read и инкремент и write от начала и до конца не будут прерываться никакими другими цепочками.

Этого можно добиться двумя путями

1. переписать полностью на синхронный код, т.е. убрать все await и async. Тогда это гарантируется синхронным однопоточным исполнителем.

2. завернуть read-increment-write в очередь, эдакий асинхронный мутекс. Соответсвенно, снова никто вклиниваться не сможет.