Как я могу узнать, не злоупотребляю ли я многопоточностью?

15

В настоящее время я чувствую, что использую многопоточность.

У меня есть 3 типа данных, A, B и C.

Каждый Aможет быть преобразован в несколько Bs, и каждый Bможет быть преобразован в несколько Cs.

Я заинтересован только в лечении Cс.

Я мог бы написать это довольно легко с парой функций преобразования. Но я поймал себя на реализацию его нитками, три очереди ( queue_a, queue_bи queue_c). Два потока выполняют разные преобразования и один рабочий:

  • ConverterAчитает queue_aи пишет вqueue_b
  • ConverterBчитает queue_bи пишет вqueue_c
  • Worker обрабатывает каждый элемент из queue_c

Преобразования довольно приземленные, и я не знаю, слишком ли сложна эта модель. Но это кажется мне чрезвычайно надежным. Каждый «конвертер» может начать работать даже до того, как данные поступят в очереди, и в любой момент в коде я могу просто «отправить» новые As или Bs, и это вызовет конвейер преобразования, который, в свою очередь, вызовет задание работника. нить.

Даже полученный код выглядит проще. Но я все еще не уверен, злоупотребляю ли я темами для чего-то простого.

exhuma
источник
5
Я думаю, что этот вопрос нужно немного сократить, чтобы преследовать его. Название также вводит в заблуждение - звучит так, как будто вы собираетесь начать разглагольствовать (хотя это не так). Может быть, вы должны спросить что-то ближе к "Как я могу сказать, если я злоупотребляю многопоточностью?"
KChaloux
@KChaloux Я согласен. Я отредактировал это, и надеюсь, что это захватит мои мысли немного лучше.
exhuma
4
@ exhuma Отлично. Ваш -1 становится +1
KChaloux
3
@KChaloux ... разница, которую посещение туалета может сделать для вашего мыслительного процесса ... :)
exhuma
В этой интерактивной PDF-книге «Руководство по оптимизации зрелых систем» (только что опубликованной несколько дней назад) рассказывается о систематических эффектах, при которых влияние модуля на общую производительность системы иногда может превышать долю времени выполнения модуля.
Rwong

Ответы:

16

Почти всегда проще мыслить последовательно, а затем модифицировать эту логику, чтобы лучше работать с потоками. И, как говорится в выражении: «Если оно не сломано, не чините его». Большинство программистов не используют потоки просто потому, что нет необходимости их использовать.

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

Также учтите, что системы, которые выделяют для процесса только один ЦП, будут моделировать несколько потоков одним потоком, чтобы сэкономить ресурсы (это не часто случается с современными компьютерами, хотя приложения для смартфонов все еще очень подвержены такому злоупотреблению). В этом случае, даже если вы устраняете узкие места с помощью потоков, на самом деле это будет медленнее, чем если бы вы вообще не использовали потоки.

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

Так что вы должны использовать темы в любом случае? Что ж, здоровое знание потоков - это, конечно, неплохая вещь, особенно если ты в этом разбираешься. Однако в последнее время движение было направлено на однопоточные языки, такие как node.js. Одним из основных преимуществ наличия одного потока является то, что его легко масштабировать, и некоторые оптимизации могут быть выполнены, если вы знаете, что инструкции должны выполняться последовательно (даже если оптимизация может означать, что инструкции, которые могут выполняться параллельно, могут работать асинхронно).

Тем не менее, я говорю, делай то, что тебе удобнее. По моему опыту, написание программы, которую вы понимаете, имеет более высокий приоритет, чем заставить ее работать быстрее. Просто убедитесь, что вы используете потоки, если считаете, что это помогает вам писать программу, а не потому, что вы хотите, чтобы она работала быстрее, поскольку вам не следует беспокоиться о производительности так сильно, как при написании программы (оптимизация важна, но тоже могу подождать).

Нил
источник
Вы делаете интересные моменты. В моем случае конверсионный конвейер это не про производительность. Речь идет о простоте кода / удобочитаемости. Рабочий поток является о производительности. Каждая заключительная задача выполняется на удаленной машине, а отправка нескольких заданий делает ее выполнение значительно быстрее.
exhuma
2
@exhuma Помимо параллельного выполнения через несколько потоков, вы также можете использовать асинхронные методы, такие как Futures / Promises, или стиль, ориентированный на обратный вызов. Обратите внимание, что вы можете моделировать конвейеры, связывая итераторы / потоки; нет необходимости фактически использовать потоки - за исключением случаев, когда вы хотите использовать несколько процессоров (в сетевом коде это почти никогда не происходит)
amon
@exhuma Да, потоки помогают с производительностью в целом. Я хотел сказать, что если вы не делаете это, потому что это слишком медленно, то вы должны делать это, потому что это помогает вам писать свою программу. Оптимизация всегда должна прийти позже. Может даже случиться так, что удаление потоков из вашей программы оптимизирует ее (хотя это не так для большинства программистов).
Нил
OT: я люблю твой аватар. Заставляет меня улыбаться.
Марьян Венема
@ exhuma, я согласен с этим ответом, но я бы добавил к нему, что если вы собираетесь использовать потоки для простоты кода, это нормально, но будьте очень осторожны, чтобы вы понимали безопасность потоков и потенциальные ошибки с несколькими потоками. То, что может показаться простым кусочком многопоточного кода, может легко иметь скрытые условия гонки, что может привести к целому ряду очень трудных для отслеживания ошибок.
Бен Ли