Почему создание нового потока дорого?

#.net #multithreading #clr #threadpool

#.net #многопоточность #clr #threadpool

Вопрос:

Я много читал .Сетевые ресурсы говорят мне, что я должен использовать поток пула потоков, а не создавать экземпляр нового потока самостоятельно. Они говорят, что вы должны это сделать, потому что создание экземпляра нового потока — дорогостоящая операция. Что происходит во время создания потока, что делает его дорогостоящей операцией?

Комментарии:

1. Ну, во-первых, среда выполнения выделяет 1 МБ памяти для стекового пространства нового потока…

Ответ №1:

Все относительно. Создание нового потока обходится дорого… относительно того, чтобы не создавать его. Если вы не выполняете много работы для каждого потока, работа, связанная с созданием и удалением потоков, потенциально может составлять измеримую часть вашего процессорного времени. Но это дешево по сравнению с созданием нового процесса, особенно в Windows.

Также обычно лучше использовать threadpool, потому что он настроен так, чтобы помочь вам избежать одновременного использования слишком большого количества потоков. Вам редко требуется, чтобы одновременно было активировано более нескольких потоков, иначе вы потратите много процессорного времени на переключение контекста между ними всеми. Использование threadpool управляет этим за вас, поскольку дополнительные запросы помещаются в очередь до тех пор, пока рабочий поток не будет готов.

Комментарии:

1. Если ожидается, что задача будет выполняться до завершения без какой-либо длительной блокировки, использование threadpool позволит избежать необходимости делить процессор между слишком большим количеством потоков, которые все хотят выполняться одновременно. Однако, если ожидается, что задача будет заблокирована, ее, вероятно, следует запускать как отдельный поток.

Ответ №2:

Каждому потоку по умолчанию выделяется 1 МБ памяти. Это может быстро стать дорогостоящим.

Ответ №3:

Есть несколько факторов. Одно из упомянутых — это память для стека. Поскольку память стека не обрабатывается обычным распределителем GC, используемым для объектов, создание стека потока и затем отказ от него сильно отличается от создания объектов кучи объемом в мегабайт и отказа от них.

Другой фактор, о котором еще не упоминалось, — это стоимость, связанная с такими вещами, как threadstatic переменные. В некоторых системах, которые требуют, чтобы все статические переменные потока, которые может использовать поток, определялись перед запуском потока, запуск нового потока потребовал бы инициализации всех статических переменных потока. Поскольку .net позволяет потокам динамически добавлять переменные threadstatic, используемые структуры данных отличаются. Тем не менее, инициализация таких структур данных при запуске потока не является бесплатной.

Ответ №4:

Threadpool предназначен не только для снижения затрат на создание и уничтожение потоков и не только для экономии памяти при меньшем количестве стеков. Реальное преимущество этого позволяет избежать одновременного использования слишком большого количества активных потоков и свести к минимуму переключение контекста при запуске серверного приложения. Даже если вы не пишете серверное приложение, threadpool просто более приятная абстракция, чем асинхронная операция запуска потоков, получение уведомления по завершении или выполнение обратного вызова по завершении, и пусть ОС или среда выполнения сами решают, сколько потоков создать.