Thread vs ThreadPool


137

Яка різниця між використанням нової нитки та використанням потоку з пулу ниток? Які переваги від продуктивності існують і чому я повинен розглянути можливість використання потоку з пулу, а не того, який я явно створив? Я тут конкретно думаю про .NET, але загальні приклади чудові.

Відповіді:


110

Набір ниток забезпечить переваги для частих і порівняно коротких операцій

  • Повторне використання потоків, які вже були створені замість створення нових (дорогий процес)
  • Викидання швидкості створення потоку, коли виникає кількість запитів на нові робочі елементи (я вважаю, це лише в .NET 3.5)

    • Якщо ви ставите в чергу 100 завдань пулу ниток, він використовуватиме лише стільки потоків, скільки вже створено для обслуговування цих запитів (наприклад, 10 наприклад). Пул потоків здійснюватиме часті перевірки (я вважаю, кожні 500 мс в 3,5 SP1), і якщо є чергові завдання, він зробить одну нову нитку. Якщо ваші завдання швидкі, то кількість нових потоків буде невеликою, і повторне використання 10 або більше потоків для коротких завдань буде швидше, ніж створення 100 ниток вперед.

    • Якщо у вашому навантаженні постійно надходить велика кількість запитів на пул потоків, то пул потоків налаштовується на ваше робоче навантаження, створюючи більше потоків у пулі вищевказаним процесом, так що для обробки запитів доступна більша кількість потоків

    • Перевірте тут, щоб отримати більш детальну інформацію про те, як функціонує пул потоків під кришкою

Створення нового потоку самостійно було б доречнішим, якщо робота буде тривати відносно довго (можливо, приблизно секунди або двох, але це залежить від конкретної ситуації)

@Krzysztof - Нитки пулу ниток - це фонові нитки, які зупиняться, коли основна нитка закінчиться. Створені вручну рушії за замовчуванням виходять на передній план (продовжуватимуться працювати після закінчення основного потоку), але їх можна встановити на фон перед тим, як викликати на них Пуск.


5
Єдине, що мені цікаво, це наступне твердження від MSDN ( msdn.microsoft.com/en-us/library/1c9txz50.aspx ) "Фоновий потік виконується лише тоді, коли кількість виконуваних потоків переднього плану менше, ніж кількість процесорів . ". Так це означає, що при поділі розробки між сердечниками пріоритетні нитки отримують пріоритет?
cdiggins

1
➤ Ви не можете перервати або перервати нитку з пулу ниток. ➤ Ви не можете приєднатись до потоку з пулу потоків. Для цього потрібно скористатися деякими іншими механізмами
Зінов,

14

Нитковий пул .NET керував: -

  • Розміри себе залежно від поточного навантаження та наявного обладнання
  • Містить робочі потоки та потоки порту завершення (які спеціально використовуються для обслуговування IO)
  • Оптимізований для великої кількості відносно короткочасних операцій

Існують інші реалізації пулу потоків, які можуть бути більш підходящими для тривалих операцій.

Зокрема, використовуйте пул потоків, щоб запобігти створенню вашої програми занадто багато потоків. Найважливішою особливістю нитки є робоча черга. Тобто, після того, як ваша машина буде достатньо зайнята, потік потокових запитів буде чергувати запити, а не одразу ж створювати більше ниток.

Отже, якщо ви створите невелику, обмежену кількість ниток, створіть їх самостійно. Якщо ви не в змозі визначити, скільки потоків може бути створено (наприклад, вони створені у відповідь на вхідний ввід), і їх робота буде короткостроковою, використовуйте пул ниток. Якщо ви не знаєте, скільки їх буде, але їх робота буде тривалою, на платформі немає нічого, що допоможе вам - але ви, можливо, зможете знайти альтернативні варіанти впровадження потокових груп, які підходять.


Чи можете ви користуватися портами завершення без пулу потоків? Я був припущений, що методи асинхронного вводу / виводу є єдиним способом (у .NET) і що вони використовують
пулову

10

також

new Thread().Start()

породжує нитку переднього плану, яка не загине, якщо закрити програму. Нитки ThreadPool - це фонові нитки, які відмирають, коли ви закриваєте додаток.


11
Ви завжди можете встановити нитку на фон. За замовчуванням вони просто передній план.
Кріс Еріксон

3
nemo: var t = нова тема (...); t.BackgroundThread = вірно; t.Start ();
Рікардо Аморес

18
Пояснення щодо терміна "програма". Настільний додаток працює в процесі і має щонайменше один потік переднього плану, який управляє інтерфейсом користувача. Цей процес триватиме до тих пір, поки він не матиме нитки переднього плану. Коли ви закриєте настільний додаток, нитка інтерфейсу переднього плану зупиняється, але ви не обов'язково зупиняли процес, якщо він має інші потоки переднього плану.
G-Wiz

8

Мене цікавило відносне використання ресурсів для них, і я застосував орієнтир на своєму двоядерному ноутбуці Intel i5 2012 року, використовуючи версію .net 4.0, побудовану на Windows 8. Починати пул ниток в середньому за 0,035 мс, щоб нитки займали в середньому 5,06 РС. Іншими словами, нитка в пулі починалася приблизно на 300 разів швидше для великої кількості короткотривалих ниток. Принаймні, у випробуваному діапазоні (100-2000) ниток, загальний час на одну нитку здавався досить постійним.

Це ідентифікаційний код:

    for (int i = 0; i < ThreadCount; i++) {
        Task.Run(() => { });
    }

    for (int i = 0; i < ThreadCount; i++) {
        var t = new Thread(() => { });
        t.Start();
    }

введіть тут опис зображення


5
Я думаю, що це тому, що ThreadPool використовує створені теми замість створення нових (що коштує дорого)
fabriciorissetto


1

Місцеве зберігання ниток - це не дуже гарна ідея для пулів ниток. Це дає ниткам "тотожність"; не всі нитки вже рівні. Тепер пули ниток особливо корисні, якщо вам просто потрібна купа однакових ниток, готова виконати свою роботу без створення накладних витрат.


1

Якщо вам потрібно багато ниток, ви, ймовірно, хочете використовувати ThreadPool. Вони повторно використовують нитки, економлячи накладні витрати на створення ниток.

Якщо вам потрібна лише одна нитка, щоб щось зробити, Thread - це, мабуть, найпростіше.


1

Основна потреба в нитках theadpool полягає в тому, щоб вирішувати короткі невеликі завдання, які, як очікується, завершаться майже миттєво. Апаратні обробники переривань часто запускаються в контексті складання, який не підходить для коду, який не є ядром, але апаратний обробник переривань може виявити, що зворотний виклик завершення вводу / виводу в режимі користувача повинен бути запущений якнайшвидше. Створення нової нитки з метою запуску такої речі було б масовим надмірним. Наявність декількох попередньо створених потоків, які можна відправити для запуску зворотних викликів завершення вводу / виводу або інших подібних речей, набагато ефективніше.

Ключовим аспектом таких потоків є те, що якщо методи завершення вводу / виводу завжди завершуються по суті миттєво і ніколи не блокуються, а кількість таких потоків, які в даний час виконують такі методи, принаймні дорівнює кількості процесорів, єдиний спосіб будь-якого іншого потоку може запускатися до завершення одного з вищезазначених методів, якщо один з блоків інших методів або час його виконання перевищує звичайний відрізок часу для нарізки; жоден з цих випадків не повинен траплятися дуже часто, якщо пул потоків використовується за призначенням

Якщо метод не може очікувати виходу протягом 100 мс або більше, коли він починає виконання, метод повинен бути виконаний за допомогою інших засобів, крім основного пулу потоків. Якщо у вас є безліч завдань, які є інтенсивними процесорами, але не блокуються, може бути корисним відправлення їх за допомогою пулу ниток додатків (по одному на ядро ​​CPU), який є окремим від "основного" потоку, оскільки використовуєте більше потоків, ніж ядер, будуть контрпродуктивними при виконанні завдань, що не блокують процесор. Якщо, однак, метод займе секунду або більше часу, і він буде витрачати більшу частину свого часу блокованим, метод, ймовірно, повинен бути запущений у спеціальній потоці, і майже напевно не повинен бути запущений у потоці основного потоку. Якщо тривалу операцію потрібно викликати щось на зразок зворотного виклику вводу / виводу,


0

Взагалі (я ніколи не використовував .NET), пул потоків використовувався б для управління ресурсами. Це дозволяє конфігурувати обмеження у вашому програмному забезпеченні. Це також можна зробити з міркувань продуктивності, оскільки створення нових потоків може бути дорогим.

Можуть бути і конкретні системні причини. У Java (знову ж я не знаю, чи це стосується .NET), менеджер потоків може застосовувати конкретні змінні потоку, оскільки кожен потік витягується з пулу, і скасовує їх, коли вони повертаються (звичайний спосіб передавати щось на зразок тотожність).

Приклад обмеження: у мене є лише 10 db-з'єднань, тому я дозволяв би отримати лише 10 робочих потоків для доступу до бази даних.

Це не означає, що ви не повинні створювати власні теми, але є умови, при яких є сенс використовувати пул.


0

Використання пулу - хороша ідея, якщо ви не знаєте чи не можете контролювати, скільки ниток буде створено.

Просто маєте проблему з формою, використовуючи потік для оновлення деякого поля з бази даних щодо події, що змінюється в позиції управління списком (уникайте freez). Мій користувач зайняв помилку в базі даних (занадто багато з'єднань з Access), оскільки він занадто швидко змінював позицію списку ...

Я знаю, що є інший спосіб вирішити базову проблему (включаючи не використання доступу), але об'єднання - це гарний початок.


0

Нитка :

  1. Створення потоку набагато повільніше, ніж використання пулу Thread.
  2. Ви можете змінити пріоритет потоку.
  3. Максимальна кількість потоків у процесі, пов'язаному з ресурсами.
  4. Нитка знаходиться на рівні ОС і контролюється ОС.
  5. Використання теми є кращим варіантом, коли завдання відносно тривале

Нитка :

  1. Запуск теми в пулі потоків набагато швидше, ніж безпосередньо створення теми.
  2. Ви не можете змінити пріоритет запуску потоку на основі пулу потоків.
  3. На процес існує лише один пул потоків.
  4. Пулом ниток керує CLR.
  5. Басейн з нитками корисний для короткочасної роботи.
  6. Кількість ниток у пулі ниток залежить від завантаження програми.
  7. Завдання TPL виконуються на основі пулу потоків
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.