Більшість відповідей вище стосуються продуктивності та одночасної роботи. Я збираюся підійти до цього з іншого кута.
Візьмемо випадок, скажімо, спрощеної програми емуляції терміналу. Ви повинні виконати такі дії:
- стежте за вхідними символами з віддаленої системи та показуйте їх
- стежте за предметами, які надходять з клавіатури, і надсилайте їх у віддалену систему
(Реальні емулятори терміналів роблять більше, включаючи потенційно повторювані речі, які ви вводите на дисплей, але зараз ми передамо це.)
Тепер цикл для читання з віддаленого просто, відповідно до наступного псевдокоду:
while get-character-from-remote:
print-to-screen character
Цикл моніторингу клавіатури та надсилання також простий:
while get-character-from-keyboard:
send-to-remote character
Однак проблема полягає в тому, що вам потрібно це робити одночасно. Код тепер повинен виглядати приблизно так, якщо у вас немає нитки:
loop:
check-for-remote-character
if remote-character-is-ready:
print-to-screen character
check-for-keyboard-entry
if keyboard-is-ready:
send-to-remote character
Логіка навіть у цьому навмисно спрощеному прикладі, який не враховує реальну складність комунікацій, є досить заплутаною. Однак, нанизуючи різьблення, навіть на одному ядрі, дві петлі псевдокоду можуть існувати незалежно, не переплітаючи їх логіку. Оскільки обидва потоки будуть в основному пов'язані з входом / виводом, вони не накладають великого навантаження на процесор, хоча вони, строго кажучи, більше витрачають ресурси процесора, ніж інтегрований цикл.
Тепер звичайно використання в реальному світі складніше, ніж вище. Але складність інтегрованого циклу зростає експоненціально, оскільки ви додаєте більше проблем до програми. Логіка стає все більш фрагментарною, і вам доведеться почати використовувати такі методи, як державні машини, підпрограми та ін., Щоб все можна було керувати. Керований, але не читабельний. Нитка підтримує код читабельнішим.
То чому б ви не використовували різьблення?
Добре, якщо ваші завдання пов'язані з процесором замість введення-виводу, нанизування фактично уповільнює вашу систему. Продуктивність постраждає. Дуже багато, у багатьох випадках. ("Зміна" - це поширена проблема, якщо ви скидаєте занадто багато потоків, пов'язаних з процесором. Ви закінчуєте витрачати більше часу на зміну активних потоків, ніж ви самі працюєте з вмістом ниток.) Крім того, одна з причин, за якими логіка вище настільки простий, що я дуже свідомо вибрав спрощений (і нереальний) приклад. Якщо ви хотіли повторити те, що було набрано на екрані, тоді у вас з’явився новий світ боляче, коли ви впроваджуєте блокування спільних ресурсів. Що стосується лише одного спільного ресурсу, це не стільки проблема, але це стає все більшою і більшою проблемою, оскільки у вас є більше ресурсів для спільного використання.
Отже, врешті-решт, нитка - це багато чого. Наприклад, мова йде про те, щоб зробити процеси, пов'язані з входом / виведенням, більш чуйними (навіть якщо загалом менш ефективними), як уже говорили деякі. Йдеться також про полегшення дотримання логіки (але лише якщо ви мінімізуєте загальний стан). Йдеться про багато матеріалів, і ви повинні вирішити, чи переваги її переважують її недоліки в кожному конкретному випадку.