Ответ
Конкурентность — это свойство системы, при котором несколько задач (потоков, процессов, корутин) выполняются в перекрывающиеся промежутки времени, создавая иллюзию параллельного выполнения. Ключевой момент — управление выполнением нескольких задач в условиях, когда для их реального параллельного выполнения может не хватать физических ресурсов (ядер CPU).
Конкурентность vs. Параллелизм:
- Конкурентность — это дизайн системы, структура программы, способная работать над несколькими задачами одновременно. Она возможна даже на одном ядре CPU за счет переключения контекста.
- Параллелизм — это реальное одновременное выполнение задач на нескольких ядрах или процессорах. Параллелизм — это один из способов реализации конкурентности.
Пример конкурентности на одном ядре (асинхронный код C#):
public async Task ServeMultipleClientsAsync()
{
// Запускаем три "долгих" I/O задачи конкурентно (например, запросы к БД или API).
// Они не выполняют вычисления на CPU, а ждут ответа от внешних ресурсов.
Task<int> dbQueryTask = QueryDatabaseAsync();
Task<string> apiCallTask = CallExternalApiAsync();
Task<FileStream> fileReadTask = ReadLargeFileAsync();
// Ожидаем завершения всех задач. Пока одна задача "ждет", поток может быть
// использован для обработки других задач или запросов.
await Task.WhenAll(dbQueryTask, apiCallTask, fileReadTask);
Console.WriteLine($"Results: {dbQueryTask.Result}, {apiCallTask.Result}");
}
private async Task<int> QueryDatabaseAsync()
{
await Task.Delay(1000); // Имитация долгого I/O-операции
return 42;
}
Основные проблемы конкурентности и их решения:
- Состояние гонки (Race Condition): Неопределенный результат из-за порядка выполнения потоков.
- Решение: Использование блокировок (
lock,Mutex), потокобезопасных коллекций, неизменяемых (immutable) структур данных.
- Решение: Использование блокировок (
- Взаимная блокировка (Deadlock): Два или более потока бесконечно ждут друг друга.
- Решение: Упорядочивание захвата блокировок, использование
Monitor.TryEnterс таймаутом,CancellationToken.
- Решение: Упорядочивание захвата блокировок, использование
- Голодание (Starvation): Поток не может получить доступ к общему ресурсу.
- Решение: Справедливые (fair) примитивы синхронизации, правильный дизайн приоритетов.
Модели реализации конкурентности в .NET:
- Многопоточность (Threads): Низкоуровневая модель.
ThreadPoolдля эффективного управления потоками. - Асинхронное программирование (async/await): Модель, идеально подходящая для I/O-операций, позволяющая освобождать потоки во время ожидания.
- Параллельные циклы (Parallel.For, PLINQ): Для распараллеливания CPU-связанных задач.
- Каналы (Channels,
System.Threading.Channels): Для реализации шаблона Producer-Consumer с высокой пропускной способностью.