LINUX.ORG.RU

Нужна ли многопоточность?

 ,


1

5

Возникли вопросы после прочтения вброса Алана Кокса в статье:

Компьютер — это конечный автомат. Потоковое программирование нужно тем, кто не умеет программировать конечные автоматы.

Не особо вдаваясь в теорию, сразу пошёл контраргумент о многоядерных машинах. Но потом, подумал, ведь и здесь их в принципе могут заменить n тасков распределённого приложения на n ядер, всем остальным пусть занимается Linux. А то и вообще многоядерные машины не нужны, ведь https://www.linux.org.ru/forum/talks/9156237...

Есть вопросы по теории конечных автоматов. Прочитав статью на википедии суть особо не чувствую, но возникла аналогия, что многопоточное приложение это несколько групп сборщиков - каждая собирает по вертолёту, а КА - конвейер производящий автомобили.

★★★★★

Последнее исправление: CYB3R (всего исправлений: 2)
Ответ на: комментарий от dave

Event-driven или автоматное программирование. Да, сам следишь чтобы у тебя ничего не подвисало и на одном куске кода долго не задерживалось. Бесконечный цикла и в нем только меняешь состояния, на основе тех, которые уже есть и входных данных. Алгоритмы все, заточенные под линейное программирование перерабатываешь под автомат. Ну или планировщик свой велосипедишь внутри прриложения. Даже protothreads можно попробовать заюзать.

quowah
()
Ответ на: комментарий от quowah

Фигня все. Десктопное приложение является пассивным. Оно отвечает на запросы системного окружения обработать те или иные события. Обработка должна быть максимально быстрой. Никакие конечные автоматы и никакое event-driven тут не помогут, чтобы не подтормаживал интерфейс. Некуда совать такой код. Нужно, чтобы приложение стало активным (актером :), а для этого придумали как раз потоки и процессы.

Более того, на одноядерной системе многопоточность реализуется, скорее всего, как event-driven (+ прерывания по таймеру). Все не так просто.

dave ★★★★★
()
Ответ на: комментарий от drBatty

Не особо вдаваясь в теорию, сразу пошёл контраргумент о многоядерных машинах.

не было у него многоядерной машины. И даже многопроцессорной.

У Кокса - была. Именно он делал первые работы по SMP в Linux.

А фразу Кокса ты неправильно понимаешь

Да что там понимать? Троллинг^WШутка и есть шутка.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

У Кокса - была. Именно он делал первые работы по SMP в Linux.

да? Ну значит забыл уже. Давно это было.

Троллинг^WШутка и есть шутка.

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

drBatty ★★
()
Ответ на: комментарий от nanoolinux

тред в моём понимании это когда зашареные данные есть

у тебя очень неортодоксальное понимание треда

в эрланге есть зашареные данные?

да

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

неортодоксальное понимание треда

а у тебя другое? можешь раскрыть? своими словами.

ets

Прочитай хотя бы что там в разделе про concurrency пишут и удивись.

nanoolinux ★★★★
()
Ответ на: комментарий от jtootf

у тебя очень неортодоксальное понимание треда

По-моему, самое что ни на есть классическое понимание.

anonymous
()
Ответ на: комментарий от nanoolinux

а у тебя другое?

абстракция потока выполнения, получающая от планировщика кванты процессорного времени

с этой точки зрения потоки, находящиеся в разных процессах - всё равно потоки, хоть памяти при этом они и не делят

Прочитай хотя бы

ты мушку-то спили, а

удивись

чему? отсутствию встроенной синхронизации? ну так в C её тоже нет. и в C++

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

абстракция потока выполнения, получающая от планировщика кванты процессорного времени

В чём тогда с этой т.з. разница между процессом и потоком? Зачем вообще вводить понятие потока, если есть процессы, которым планировщик выделяет ресурс в виде процессорного времени?

ну так в C её тоже нет

К чему это сравнение? В эрланге нету дофига вещей, которые есть в С и наоборот. Но зашареной памяти в ерланге нет, хоть убейся. С ets можно только просимулировать что-то похожее, за что ты очень сильно вероятно в будущем получишь головную боль. Даже начинающему эрлангисту понятно, что если всё завязано на передаче данных через ets, то явно что-то делается не так и архитектуру надо менять.

ты мушку-то спили

ну извини.

nanoolinux ★★★★
()
Последнее исправление: nanoolinux (всего исправлений: 1)

Ну что тут можно сказать? Даже простая портниха поймет: на швейной машинке шить гораздо быстрее, чем иголкой, а в ней две нити, а иначе — никак.

proud_anon ★★★★★
()
Ответ на: комментарий от nanoolinux

В чём тогда с этой т.з. разница между процессом и потоком?

любой процесс является потоком (по крайней мере одним), потому говорить о разнице здесь надо осторожно

Зачем вообще вводить понятие потока, если есть процессы

скорей наоборот. в той же Singularity потоки есть, а процессов (изолированного адресного пространства) нет

процессы, которым планировщик выделяет ресурс в виде процессорного времени

я не силён в линуксовом ядре, но в QNX (например) планировщик о процессах не знает вообще ничего. для него процесс - это какой-то чёрный ящик, из которого наверх торчит минимум один поток, который и надо шедулить

зашареной памяти в ерланге нет

это неверно

если всё завязано на передаче данных через ets, то явно что-то делается не так и архитектуру надо менять

философия языка и его возможности - разные вещи. если в C++ всё делается через глобальные переменные, то это тоже намекает на проблемы с архитектурой, однако такой вариант развития событий не даёт права говорить, что в C++ нет глобальных переменных

потоки в Erlang могут шарить память. ты можешь (явно) не пользоваться этой возможностью точно так же, как можешь не использовать общее адресное пространство потоков в C (используя только TLS и какой-нибудь IPC для общения). потоки в Erlang являются абстракциями потока выполнения - сущностями, получающими процессорное время; подозреваю, что с отображением «многие ко многим» - с количеством системных потоков, линейно зависимым от количества доступных ядер (во всяком случае, так делает GHC RTS)

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

любой процесс является потоком (по крайней мере одним), потому говорить о разнице здесь надо осторожно

Процесс является адресным пространством, чего тут осторожничать? Осторожно нужно говорить о том, что процесс явлется сущностью, потребляющей ресурсы.

И таки да, обычное, классическое понимание multithreading - это несколько нитей в общем адресном пространстве, с синхронизацией семафорами и подобными средствами (т.е. message passing, даже если используется, не является основным средством). Для более сложных вариантов используются специальные термины вроде акторов, CSP, STM и прочего.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

обычное, классическое понимание multithreading - это несколько нитей в общем адресном пространстве

мне кажется, факт наличия одного контекста выполнения (падение всех нитей одновременно в случае SIG<что-нибудь плохое>) важней общего адресного пространства (которое один чёрт эмулируется маппингами), но пусть будет так

с синхронизацией семафорами и подобными средствами

что семафоры, что мьютексы в наш просвещённый век замечательно шарятся между процессами и неспецифичны для описываемого тобой сценария

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

мне кажется, факт наличия одного контекста выполнения (падение всех нитей одновременно в случае SIG<что-нибудь плохое>) важней общего адресного пространства

Ну, во-первых, не очень понятно, что такое «контекст выполнения» (так обычно называют что-то, _специфичное_ для нити), во-вторых, всё же нет. Multithreading - это принципиально модель программирования с общей памятью, когда по умолчанию всё общее (я бы сказал, что в multithreading вообще нет не-разделяемой памяти, но не хочу ввязываться в дискуссию о методах реализации TLS).

что семафоры, что мьютексы в наш просвещённый век замечательно шарятся между процессами и неспецифичны для описываемого тобой сценария

Их шаринг был еще в те времена, когда нитей не было, так что нерелевантно.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Multithreading - это принципиально модель программирования с общей памятью

на этом месте я могу придраться к тому, что в исходном посте подвергалось сомнению не наличие multithreading'а как модели программирования, а наличие потока выполнения как такового. модель в твоей трактовке, к слову, с нитями напрямую не связана

нерелевантно

ты загнал меня в положение ко

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

Ты на мой вопрос так и не ответил, придёться повторить. Зачем вообще было введено понятие «поток» если уже есть «процесс»? Если между ними нет разницы, тогда

любой процесс является потоком

масло масляное. Ты понимаешь о чем я? Должно быть нечто такое, что заставило сообщество ввести это понятие. Так вот вопрос в том, чем это нечто является.

это неверно

О какой зашареной памяти ты ведёшь речь если в эрланге напрямую с памятью вообще нельзя работать? Естественно можно написать порт/драйвер, но его всё равно придётся писать на чём-то другом.

потоки в Erlang

Нету в эрланге потоков. Там процессы.

могут шарить память

Пруф или небыло. Мне самому интересно стало.

потоков... IPC...

IPC это аббревиатура от inter *process* communication. Потокам никакой IPC ненужен, им нужны только средства обеспечения атомарности доступа к зашаненой памяти. Архитектурно сделать это сложно, поэтому приходиться юзать всякие мутексы-футексы и Ко. Но это всё равно в тыщи раз быстрее любого IPC и собственно для этого потоки и были придуманы. Это кстати и есть ответ на мой вопрос, который я тебе задавал, ну да ладно, пусть будет.

nanoolinux ★★★★
()
Ответ на: комментарий от jtootf

Ну, «в Эрланге нет тредов» мы просто отметаем.

модель в твоей трактовке, к слову, с нитями напрямую не связана

Как это не связана? Параллельное исполнение на единой памяти есть multithreading, а multithreading есть параллельное исполнение на единой памяти (для протокола: единая память здесь служит и основным механизмом коммуникаций).

Кстати, а какая еще модель предполагает _единое_ адресное пространство? Только не говори о vfork и подобных кладжах, на которых делались ранние pthreads.

tailgunner ★★★★★
()
Ответ на: комментарий от nanoolinux

Зачем вообще было введено понятие «поток» если уже есть «процесс»? Если между ними нет разницы

Есть разница. Процесс характеризуется отдельным адресным пространством, а поток разделяет адресное пространство с другими потоками, которые выполняются в контексте одного процесса.

IPC это аббревиатура от inter *process* communication. Потокам никакой IPC ненужен, им нужны только средства обеспечения атомарности доступа к зашаненой памяти.

Это зависит от реализации. ЕМНИП, в L4 IPC осуществляется между потоками (threads), а в Mach между процессами (задачами, tasks).

DesertFox
()
Последнее исправление: DesertFox (всего исправлений: 2)
Ответ на: комментарий от DesertFox

L4 IPC осуществляется между потоками (threads), а в Mach между процессами (задачами, tasks)

в QNX родной IPC (сообщения QNet) соединяет потоки и является прозрачным в смысле адресного пространства и сети - потоки могут принадлежать разным процессам на разных физических машинах; но вполне при этом могут и шарить какую-то память (в таком случае будет выполнена очевидная оптимизация). ну, в копилку примеров

jtootf ★★★★★
()
Ответ на: комментарий от tailgunner

единая память здесь служит и основным механизмом коммуникаций

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

какая еще модель предполагает _единое_ адресное пространство?

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

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

(green threads) GHC отображаются на системные потоки, но в качестве основного механизма коммуникации используют совсем другие механизмы. если это не multithreading, то что это?

Тебе виднее, как это называется в Хаскеле. Но следует сказать, что термин multithreading устоялся еще до того, как в Хаскеле появились нити.

какая еще модель предполагает _единое_ адресное пространство?

любая, подпадающая под это определение

Я сказал «единое». Не «имеющее общие части», а «единое».

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

термин multithreading устоялся еще до того

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

Не «имеющее общие части», а «единое»

в чём практический смысл разделения этих понятий?

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

но устраивать гонку за авторитетными источниками не хочется совершенно

Я думаю, их и нет. Это именно традиция использования - насколько я вижу, сейчас более продвинутые техники распараллеливания противопоставляются именно multithreading.

Не «имеющее общие части», а «единое»

в чём практический смысл разделения этих понятий?

В стиле программирования, который это влечет.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от proud_anon

есть и с одной ниткой, и с тремя и более нитками. зависит от назначения инструмента

chg ★★★★★
()
Ответ на: комментарий от jtootf

зелёные потоки (green threads) GHC отображаются на системные потоки, но в качестве основного механизма коммуникации используют совсем другие механизмы

Но IORef, массивы, MVar и STM же вполне расшариваются между такими потоками. Вполне в духе обычных нитей (POSIX, скажем) получается, просто с собственным планировщиком и менеджером IO.

quasimoto ★★★★
()
Ответ на: комментарий от tailgunner

Не «имеющее общие части», а «единое»

в чём практический смысл разделения этих понятий?

В стиле программирования, который это влечет.

можно конкретно?

jtootf ★★★★★
()
Ответ на: комментарий от tailgunner

Ядро Linux.

ты продолжаешь говорить загадками. куда мне смотреть, чтобы увидеть разницу в стиле программирования в случае разделения всего и части адресного пространства?

я передал (userptr'ом или после mmap'а) в ядро буфер, модуль ядра мне его залочил какой-нибудь вариацией семафора на некоторое количество операций, я залип на семафоре и жду; дождался, разлочился, пошёл снова наполнять буфер. что изменилось бы, если бы буфер был выделен в общем (полностью, как ты настаиваешь, общем) адресном пространстве, а работали бы с ним разные потоки одного процесса?

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

ну тогда всё в порядке, конечно

ETS нативная реализация. И там при переходе ets/erlang вообще все копируется - так что даже в ets нету шареных данных, и конфликты невозможны кроме как на состоянии самой ETS.

Вон недавно пришлось изобрести ссылки в эрланге (СТНБ там есть process independent env в нативе - а то б пришлось вообще в натив копировать все), именно для преодоления этой фигни.

Кто-то в курсе а почему собственно в эрланге нету шареной памяти? Неасилели GC?

r ★★★★★
()
Ответ на: комментарий от jtootf

ты продолжаешь говорить загадками.

Просто ты ожидаешь чего-то сложного, а всё на самом деле просто.

куда мне смотреть, чтобы увидеть разницу в стиле программирования в случае разделения всего и части адресного пространства?

Куда смотреть - не знаю. Стиль программирования отличается тем, что приходится думать о том, какие данные шарить.

я передал (userptr'ом или после mmap'а) в ядро буфер

Я говорю о структурах данных, которыми владеет ядро. О том, как они лочатся, почитай в Documentation/filesystems/{Locking,directory-locking}.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

приходится думать о том, какие данные шарить

об этом приходится думать всегда :)

О том, как они лочатся, почитай в Documentation/filesystems/{Locking,directory-locking}.

ок, спасибо

jtootf ★★★★★
()
Ответ на: комментарий от splinter

ну можно и дом из песчинок построить, только стоит ли оно того?

ну вообще-то на ⅞ дома и строят из песчинок (пруф в википедии смотри).

drBatty ★★
()
Ответ на: комментарий от r

при переходе ets/erlang вообще все копируется

вот как. не знал, спасибо

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

приходится думать о том, какие данные шарить

об этом приходится думать всегда :)

Ну, в случае единого адресного пространства все данные уже зашарены.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

в случае единого адресного пространства все данные уже зашарены

но определиться с тем, что именно в это адресное пространство попадёт, всё равно надо. никто не шарит данные бездумно (ну, или хотелось бы, чтобы никто)

jtootf ★★★★★
()
Ответ на: комментарий от quantum-troll

Воздержусь от исследования книг 70-80 годов.

А в книгах 70-80 годов - дао

yoghurt ★★★★★
()
Ответ на: комментарий от nanoolinux

Зачем вообще вводить понятие потока, если есть процессы, которым планировщик выделяет ресурс в виде процессорного времени?

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

quantum-troll ★★★★★
()
Ответ на: комментарий от quantum-troll

не во всех ОС потоки реализованы в ядре

Я тебе даже больше скажу. В эрланге например шедулингом процессов занимается вм, а не ядро.

nanoolinux ★★★★
()
Ответ на: комментарий от jtootf

в случае единого адресного пространства все данные уже зашарены

но определиться с тем, что именно в это адресное пространство попадёт, всё равно надо

Не понял. В едином адресном пространстве уже есть всё, по определению. Со всеми вытекающими преимуществами и недостатками.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от invy

Разве мы не получаем оверхеда из-за возникающей необходимости как-то передавать данные между (теперь отдельными) адресными пространствами, если отказываемся от потоков и используем исключительно процессы?

cdshines ★★★★★
()
Ответ на: комментарий от cdshines

Зато отлаживать проще, т.к. у тебя гарантировано один процесс не испортит в адрессном прастранстве другого процесса ничего. Плюс не надо теоретически блокировать heap при выделении памяти (ну и бороться с блокировками). Кроме того тебе доступно больше vram на поток (актуально на 32-х битах).

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от r

С дискуссией - не ко мне :) Я считаю что оба средства хороши если использованы по назначению.

invy ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.