Re[20]: Можно ли избавиться от async|await?
От: mrTwister Россия  
Дата: 16.12.25 07:55
Оценка:
Здравствуйте, ·, Вы писали:

T>>Мьютекс сам по себе не позволит тебе конкурентно выполнять несколько "просессов" на одном потоке. Тебе нужно разбивать "процессы" на подзадачи, строить цепочки таскок и переключаться между ними.

·>Это понятно что модели как пишется код, конечно, разные. Но корректно продуманная кооперация требуется ровно так же.

Ну в этом смысла да, примитивы синхронизации — это механизм кооперации, с помощью которого потоки могут друг с другом о чем-то договориться.
лэт ми спик фром май харт
Re[3]: Можно ли избавиться от async|await?
От: mrTwister Россия  
Дата: 16.12.25 08:14
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Проверял или просто веришь?


S>Вот C#


S>
S>async Task<int> SumAsync(int a, int b) {
S>    return a + b;
S>}

S>var x = await SumAsync(2, 3);
S>


S>Эквивалент в Go

S>...
S>- еще хуже.

Нет, вот полный эквивалент в go:
func sum(a, b int) int {
    return a + b
}

x := sum(1, 2)


В go все функции асинхронны, у меня уже пальцы устали это писать
лэт ми спик фром май харт
Отредактировано 16.12.2025 8:15 mrTwister . Предыдущая версия . Еще …
Отредактировано 16.12.2025 8:15 mrTwister . Предыдущая версия .
Re[4]: Можно ли избавиться от async|await?
От: Shmj Ниоткуда  
Дата: 16.12.25 08:25
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> А вызов без await подсвечивается в редакторе.


Так это не ошибка — вдруг вы так и задумали — пусть себе исполняется а вы будете другое делать.
=сначала спроси у GPT=
Re[4]: Можно ли избавиться от async|await?
От: Shmj Ниоткуда  
Дата: 16.12.25 08:37
Оценка:
Здравствуйте, mrTwister, Вы писали:

S>>Эквивалент в Go

S>>...
S>>- еще хуже.

T>Нет, вот полный эквивалент в go:

T>
T>func sum(a, b int) int {
T>    return a + b
T>}

T>x := sum(1, 2)
T>


T>В go все функции асинхронны, у меня уже пальцы устали это писать


Вот что пишет всезнайка, по идее это должен знать:

  Скрытый текст

Если бы в Go все функции были асинхронными, в языке существовали бы:

  • implicit future,
  • await-поведение,
  • выражение результата,
  • continuation semantics.

Ничего этого в Go нет.
Есть только синхронные функции и оператор go, создающий параллельное исполнение.

Это проверяется типами, стеком, panic, defer, временем выполнения и спецификацией языка.



Это бесплатный, могу уточнить у платного. ОК, как вы можете подтвердить свое утверждение? Давай тут: https://go.dev/play/
=сначала спроси у GPT=
Отредактировано 16.12.2025 8:38 Shmj . Предыдущая версия .
Re[5]: Можно ли избавиться от async|await?
От: mrTwister Россия  
Дата: 16.12.25 08:45
Оценка:
Здравствуйте, Shmj, Вы писали:


S>[cut]

S>[q]
S>Если бы в Go все функции были асинхронными, в языке существовали бы:

S>

S>Ничего этого в Go нет.


Все это есть в Go, но без явных языковых конструкций.
Когда ты в Go пишешь "sum(1, 2)" тут неявно подразумевается псевдокод "await sum(1,2)". У тебя вызывающая функция до sum может выполняться в одном потоке ОС, а после "x := sum(1, 2)" может продолжить выполняться вообще в другом потоке (то есть так же, как в C# варианте).
лэт ми спик фром май харт
Отредактировано 16.12.2025 8:46 mrTwister . Предыдущая версия .
Re[4]: Можно ли избавиться от async|await?
От: Shmj Ниоткуда  
Дата: 16.12.25 08:45
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>В go все функции асинхронны, у меня уже пальцы устали это писать


Вы ошиблись:

https://telegra.ph/Go-ne-vse-funkcii-asinhronnye-12-16

https://gemini.google.com/share/3b8a2541a13c

Это платные. Пишут что даже по ассемблеру можно видеть что нет там никакой асинхронщины по умолчанию. И написало почему такое заблуждение возникло.
=сначала спроси у GPT=
Re[5]: Можно ли избавиться от async|await?
От: mrTwister Россия  
Дата: 16.12.25 08:53
Оценка: -1
Здравствуйте, Shmj, Вы писали:

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


T>>В go все функции асинхронны, у меня уже пальцы устали это писать


S>Вы ошиблись:


S>https://telegra.ph/Go-ne-vse-funkcii-asinhronnye-12-16


По умолчанию вызов функции в Go — синхронный: выполняется в текущей горутине и возвращает управление только после return


Дальше не читал. Горутина в go — это просто структура данных. Как, например, Task в .net. Не в смысле, что это аналог, в смысле что это вспомогательная структура данных для организации вычислений. Вызов функции в go блокирует горутину точно так же, как await блокирует асинхронную функцию в C#

Давай так, объясни, чем в плане поведения (а так же потребление ресурсов, потоков) отличаются C# вариант от go варианта?
async Task<int> SumAsync(int a, int b) {
    return a + b;
}

var x = await SumAsync(2, 3);


func sum(a, b int) int {
    return a + b
}
x := sum(1, 2)


подсказка: вообще ничем не отличаются, это полные аналоги
лэт ми спик фром май харт
Отредактировано 16.12.2025 8:56 mrTwister . Предыдущая версия . Еще …
Отредактировано 16.12.2025 8:54 mrTwister . Предыдущая версия .
Re[6]: Можно ли избавиться от async|await?
От: Shmj Ниоткуда  
Дата: 16.12.25 08:54
Оценка: +1
Здравствуйте, mrTwister, Вы писали:

T>Все это есть в Go, но без явных языковых конструкций.

T>Когда ты в Go пишешь "sum(1, 2)" тут неявно подразумевается псевдокод "await sum(1,2)". У тебя вызывающая функция до sum может выполняться в одном потоке ОС, а после "x := sum(1, 2)" может продолжить выполняться вообще в другом потоке (то есть так же, как в C# варианте).

Почему ты так думаешь? Попробуй доказать это в коде.

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

В Go оператор go не может вернуть промис или что-то подобное, а значит совсем другая концепция.
=сначала спроси у GPT=
Отредактировано 16.12.2025 8:56 Shmj . Предыдущая версия .
Re[6]: Можно ли избавиться от async|await?
От: Shmj Ниоткуда  
Дата: 16.12.25 08:57
Оценка: +1
Здравствуйте, mrTwister, Вы писали:

T>Дальше не читал. Горутина в go — это просто структура данных. Как, например, Task в .net. Не в смысле, что это аналог, в смысле что это вспомогательная структура данных для организации вычислений. Вызов функции в go блокирует горутину точно так же, как await блокирует асинхронную функцию в C#


T>Давай так, объясни, чем в плане поведения (а так же потребление ресурсов, потоков) отличаются C# вариант от go варианта?


Вся суть async/await — в том что можно получить Task/Promise/Future и манипулировать ими. Т.е. можете дождаться результата — а можете не дожидаться — но не просто не дожидаться — а заиметь промис, в котором будет результат.

Без возможности получить промис — все теряет смысл.
=сначала спроси у GPT=
Re[7]: Можно ли избавиться от async|await?
От: mrTwister Россия  
Дата: 16.12.25 08:58
Оценка:
Здравствуйте, Shmj, Вы писали:
вообще в другом потоке (то есть так же, как в C# варианте).

S>Почему ты так думаешь? Попробуй доказать это в коде.


S>Должна быть возможность получить что-то типа Task или Promise или Future не дожидаясь исполнения и добавить эти промисы в список, к примеру. Потом подождать пока исполнится весь список и получить результат каждого из списка.


Это все есть, но под капотом внутри рантайма go.
лэт ми спик фром май харт
Re[5]: Можно ли избавиться от async|await?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.12.25 09:01
Оценка:
Здравствуйте, Shmj, Вы писали:

S>> А вызов без await подсвечивается в редакторе.


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


Ну это предупреждение, которое можно подавить различными способами.
Предупреждён — значит вооружён!
и солнце б утром не вставало, когда бы не было меня
Re[7]: Можно ли избавиться от async|await?
От: mrTwister Россия  
Дата: 16.12.25 09:06
Оценка:
Здравствуйте, Shmj, Вы писали:


S>Вся суть async/await — в том что можно получить Task/Promise/Future и манипулировать ими. Т.е. можете дождаться результата — а можете не дожидаться — но не просто не дожидаться — а заиметь промис, в котором будет результат.


S>Без возможности получить промис — все теряет смысл.


Все это есть в go:
// Вот моя асинхронная функция
func sum(a, b int) int {
    return a + b
}

// Я могу вызвать ее и дождаться результата (поток ОС при этом не блокируется)
x := sum(1, 2)

// Я могу вызвать и не дожидаться результата (при этом несмотря на создание новой горутины, это может все работать на одном единственном потоке ОС)
go sum(1, 2)

// В крайне редких кейзах, когда мне не нужен результат прям сейчас, а нужен когда-то потом, то я могу написать
result := make(chan int)
go func(){result <- sum(1,2)}()
... куча кода
println(<-result)


Во всех вариантах это асинхронный код, который не блокирует потоки ОС и конкурентно таких функций может быть запущено сотни тысяч
лэт ми спик фром май харт
Re[8]: Можно ли избавиться от async|await?
От: Shmj Ниоткуда  
Дата: 16.12.25 09:10
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Это все есть, но под капотом внутри рантайма go.


Блажен кто верует. Вот код, зачем спорить. C#

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
    // Глобальный счетчик (общий ресурс для всех потоков)
    private static int _globalCounter = 0;

    public static async Task Main()
    {
        // Список для хранения запущенных задач (аналог Future/Promise)
        var tasks = new List<Task<int>>();
        int numberOfTasks = 10;

        Console.WriteLine("--- 1. Запуск задач ---");

        for (int i = 0; i < numberOfTasks; i++)
        {
            // Task.Run ставит задачу в очередь ThreadPool.
            // Мы НЕ используем await здесь, чтобы не блокировать цикл.
            // Мы просто сохраняем "хэндл" задачи в список.
            Task<int> task = Task.Run(async () =>
            {
                // Имитация работы (задержка 100мс), чтобы потоки точно работали параллельно
                await Task.Delay(100);

                // Атомарное увеличение счетчика. 
                // Это аналог counter++ только потокобезопасный.
                // Функция возвращает уже увеличенное значение.
                return Interlocked.Increment(ref _globalCounter);
            });

            tasks.Add(task);
        }

        Console.WriteLine($"Запущено {tasks.Count} задач. Главный поток свободен и продолжает работу...");
        
        // Здесь можно делать что-то еще, пока таски крутятся в фоне
        
        Console.WriteLine("--- 2. Ожидание выполнения ---");

        // Task.WhenAll эффективно ждет завершения всех задач из списка.
        // Он возвращает массив результатов, когда последний таск закончит работу.
        int[] results = await Task.WhenAll(tasks);

        Console.WriteLine("Все задачи завершены!");
        Console.WriteLine("--- 3. Вывод результатов ---");

        // Проходимся по полученным результатам
        // Порядок в массиве results соответствует порядку задач в списке tasks
        for (int i = 0; i < results.Length; i++)
        {
            Console.WriteLine($"Таск #{i + 1} вернул значение счетчика: {results[i]}");
        }
        
        Console.WriteLine($"Итоговое значение глобального счетчика: {_globalCounter}");
    }
}


Тут: https://dotnetfiddle.net/DYg97H

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

Вот перевод на Go — посмотри насколько криво: https://go.dev/play/p/oDoPGmB7QU1

Есть чем возразить? Очевидно что нет.
=сначала спроси у GPT=
Re[8]: Можно ли избавиться от async|await?
От: Shmj Ниоткуда  
Дата: 16.12.25 09:12
Оценка: +1
Здравствуйте, mrTwister, Вы писали:

T>
T>// Я могу вызвать и не дожидаться результата (при этом несмотря на создание новой горутины, это может все работать на одном единственном потоке ОС)
T>


Та епта, так можно и в C# 2.0 вызывать в потоке. А ты попробуй промис получить. Вся суть в возможности получить промис — а просто запустить в отдельном потоке — никакой ценности не представляет.
=сначала спроси у GPT=
Re[9]: Можно ли избавиться от async|await?
От: mrTwister Россия  
Дата: 16.12.25 09:16
Оценка:
Здравствуйте, Shmj, Вы писали:

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


T>>
T>>// Я могу вызвать и не дожидаться результата (при этом несмотря на создание новой горутины, это может все работать на одном единственном потоке ОС)
T>>


S>Та епта, так можно и в C# 2.0 вызывать в потоке. А ты попробуй промис получить. Вся суть в возможности получить промис — а просто запустить в отдельном потоке — никакой ценности не представляет.


Дак я не в потоке вызывал. Выделил главное. Ключевое слово "go" не в потоке запускает
лэт ми спик фром май харт
Re[10]: Можно ли избавиться от async|await?
От: Shmj Ниоткуда  
Дата: 16.12.25 09:19
Оценка: +1
Здравствуйте, mrTwister, Вы писали:

T>Дак я не в потоке вызывал. Выделил главное. Ключевое слово "go" не в потоке запускает


В потоке (для каждого go создается свой поток), вот доказательство: https://go.dev/play/p/oDoPGmB7QU1

Если бы не в потоке, то вывод был бы последовательный — а так какая успела — та первой счетчик и изменила.

Горутина #1 вернула значение счетчика: 6
Горутина #2 вернула значение счетчика: 2
Горутина #3 вернула значение счетчика: 7
Горутина #4 вернула значение счетчика: 5
Горутина #5 вернула значение счетчика: 1
Горутина #6 вернула значение счетчика: 3
Горутина #7 вернула значение счетчика: 10
Горутина #8 вернула значение счетчика: 9
Горутина #9 вернула значение счетчика: 8
Горутина #10 вернула значение счетчика: 4
Итоговое значение глобального счетчика: 10

=сначала спроси у GPT=
Отредактировано 16.12.2025 9:19 Shmj . Предыдущая версия .
Re[9]: Можно ли избавиться от async|await?
От: mrTwister Россия  
Дата: 16.12.25 09:38
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Вот перевод на Go — посмотри насколько криво: https://go.dev/play/p/oDoPGmB7QU1


S>Есть чем возразить? Очевидно что нет.


Тут два момента: кривость и асинхронность, предлагаю обсудить их отдельно.

Асинхронность
Оба варианта асинхронные и несмотря на запуск 10 тасок/10 горутин, будет по факту использовано скорее не 10 потоков, а меньше. Таким образом оба варианта можно, например, безопасно вызывать в http хендлере не опасаясь заблокировать работу http сервера из-за thread pool depletion

Кривость
Код по сути идентичный с поправкой на то, что в go используются чуть более низкоуровневые примитивы. Но никто не мешает написать пару хелперов на несколько строк кода и получить абсолютно идентичное решение: https://go.dev/play/p/vV97PJoKyIB
лэт ми спик фром май харт
Re[11]: Можно ли избавиться от async|await?
От: mrTwister Россия  
Дата: 16.12.25 09:46
Оценка:
Здравствуйте, Shmj, Вы писали:

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


T>>Дак я не в потоке вызывал. Выделил главное. Ключевое слово "go" не в потоке запускает


S>В потоке (для каждого go создается свой поток), вот доказательство: https://go.dev/play/p/oDoPGmB7QU1


Блин, не не спорь пожалуйста, ты же понятия не имеешь, как работает go, но споришь

S>Если бы не в потоке, то вывод был бы последовательный — а так какая успела — та первой счетчик и изменила.


Нет конечно, time.Sleep создает под капотом таймер, который при срабатывании вызывает continuation у горутины. В зависимости от того, в каком порядке сработали эти таймеры, получится разный порядок цифр.

Go выполняет горутины в тредпуле, но размер этого тредпула фиксирован и определяется при старте программы (по умолчанию равен количеству ядер процессора). При этом ты можешь запустить свою программу с переменной окружения GOMAXPROCS=1, в этом случае для выполнения всех горутин будет использоваться один единственный поток ОС, что не помешает всем горутинам выполняться "одновременно", то есть конкурентно.
лэт ми спик фром май харт
Отредактировано 16.12.2025 9:48 mrTwister . Предыдущая версия .
Re[11]: Можно ли избавиться от async|await?
От: wl. Россия  
Дата: 16.12.25 09:47
Оценка: 3 (1) -1
Здравствуйте, Shmj, Вы писали:

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


T>>Дак я не в потоке вызывал. Выделил главное. Ключевое слово "go" не в потоке запускает


S>В потоке (для каждого go создается свой поток), вот доказательство: https://go.dev/play/p/oDoPGmB7QU1


если выводит ThreadId, он всегда одинаковый: https://go.dev/play/p/EbNWMIwOBqN
Re[10]: Можно ли избавиться от async|await?
От: Shmj Ниоткуда  
Дата: 16.12.25 10:12
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Асинхронность

T>Оба варианта асинхронные

Как ты это сможешь доказать? Ок, c go — асинхронный, верю. А без go — какие ваши доказательства что оно асинхрон?

T>и несмотря на запуск 10 тасок/10 горутин, будет по факту использовано скорее не 10 потоков, а меньше.


Так это и в C# — там ThreadPool.

T>Таким образом оба варианта можно, например, безопасно вызывать в http хендлере не опасаясь заблокировать работу http сервера из-за thread pool depletion


Это не доказательство — завимсит от реализации обработки http.

Давай доказательство на твоем коде.

T>Кривость

T>Код по сути идентичный с поправкой на то, что в go используются чуть более низкоуровневые примитивы. Но никто не мешает написать пару хелперов на несколько строк кода и получить абсолютно идентичное решение: https://go.dev/play/p/vV97PJoKyIB

Это вы реализовали функционал async|await, но весьма криво — через каналы. Это раньше приводил вам.
=сначала спроси у GPT=
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.