@dlangru

Страница 110 из 719
Dmitry
10.12.2016
08:35:47
Блин, что я не так делаю:

qwe
11.12.2016
03:35:44
@DmitryBubnenkov а нужен принципиально while(True)?

не очень силен в этой части D, полагаю, что worker (это то, что передано аргументом в spawn) живет дольше tid, потому что стоит бесконечный цикл

поставьте там то же количество итераций, что и у генератора

Google
qwe
11.12.2016
03:41:46
или если хотите переменное количество итераций, то передаайте этот генератор в workder

будьте человеком)

http://ddili.org/ders/d.en/concurrency.html тут вот кажется об этом упоминается даже

@DmitryBubnenkov можешь об этом написать на форуме. А то они там с жиру бесятся со своими генерируемыми getters/setters =)

Dmitry
12.12.2016
07:38:42
qwe а как без UFCS вызывать http://forum.dlang.org/thread/vbjpwkqakqkubyruxcgi@forum.dlang.org ? Что то не соображу

Почему следующий код (кстати он в онлайн-компилере не работает) http://codepad.org/BkLvT5Ln Выводит worker: 1 только один раз

По идее же send должен 10 раз вызываться в foreach

Все, разобрался

Все же упорно не могу понять, почему код останавливается именно в этом месте:

Почему метод receive вызывается без укзания типа? https://dlang.org/phobos/std_concurrency.html#.receive

Grigirii
12.12.2016
11:56:12
а какой тип надо указывать?

Dmitry
12.12.2016
11:56:55
void

Grigirii
12.12.2016
11:57:42
не понял, где там void?

Google
Dmitry
12.12.2016
11:57:56
void receive(T...)(T ops);

Grigirii
12.12.2016
11:58:47
ну? это жеобъявление этой функции, а нужен просто вызов. как writeln(), а не void writeln()

Dmitry
12.12.2016
11:59:15
а в какой момент подобные функции объявляются?

Grigirii
12.12.2016
11:59:34
в смысле? это обычная функция, объявленная в std

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

Dmitry
12.12.2016
12:01:21
так, судя по описаню это шаблон, значит его вызывть надо receive!int а в примере вызов идет: receive( (int i))

Grigirii
12.12.2016
12:02:03
да, но есть замечательная вещь - автовыведение. тип шаблона может быть определён по типу аргумента

чтобы лишнее не писать

Dmitry
12.12.2016
12:03:08
так тогда получается: receive( (int i)) т.е. вообще тип не указывать

Grigirii
12.12.2016
12:04:05
receive((int i) {что-то с i}); как-то так. надо же с полученным i что-то делать

в примере же написано, как надо: receive( (int i) { writeln("Received an int."); }, (float f) { writeln("Received a float."); }, (Variant v) { writeln("Received some other type."); } );

Dmitry
12.12.2016
12:04:46
тоесть в одну функцию можно передавать другую функцию? просто меня смущют круглые скобки

Grigirii
12.12.2016
12:04:53
да, можно

он вызовет соответстующую функцию, когда что-то придёт от send. придёт int - вызовет ту, что принимает int, придёт float - вызовет с float

это дишный подход к реализации pattern matching по типам

Dmitry
12.12.2016
12:09:21
а какие функции еще можно одна в другую передавать таким же образом из популярных? Просто как понять какие можно передавать, а какие нет?

Grigirii
12.12.2016
12:11:02
ну банальный случай, когда ты передаёшь компоратор в функцию сортировки. когда в массиве лежат объекты, на которых не переопределено сравнение. Ди это воротит через шаблоны, а традиционно - передаём функцию, которая принимает 2 объекта и возвращает результат сравнения

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

Dmitry
12.12.2016
12:12:07
колбеки = делегаты?

Колбеками их называют т.к. в JS их так было принято называть?

Google
Grigirii
12.12.2016
12:12:46
в целом да, просто колбек - абстракция обратного вызова, делегат - один из вариантов реализации

это задолго до js было в C

Dmitry
12.12.2016
12:42:34
Так, погоди, а какой смысл в функции receive ведь она ничего не возвращает т.е. как я понимаю нельзя сделать: int x = receive

Grigirii
12.12.2016
12:44:46
нельзя, но можно передать ей функцию, в которую аргументом придёт значение

то есть вместо int x = receive(); writeln(x); пишешь receive((int x){ writeln(x); });

если ты точно знаешь, что тебе может придти только один тип, то проще использовать receiveOnly

receive нужен чтобы сделать что-то вроде switch по типу аргумента

Dmitry
12.12.2016
12:49:07
а... понял, спасибо

а все что вызывается через spawn это файберы ?

Grigirii
12.12.2016
12:50:41
это могут быть и потоки, но суть для кода у них похожая

Dmitry
12.12.2016
12:51:34
м... а почему "могут быть" т.е. как визуально (по названию методов) одно от другого отличается?

Grigirii
12.12.2016
12:54:00
ну изначально spawn это старт нового потока, так что это скорее про потоки, чем про файберы. но вообще std.concurrency написан по большей части абстрактно и тот же send работает одинакого для потоков и файберов

Dmitry
12.12.2016
12:56:44
м... блин. А что тогда: "class Thread" делает? Вроде по названию треды создает

Grigirii
12.12.2016
12:57:02
ну как бы да

Dmitry
12.12.2016
12:57:42
Просто мне не понятна логика когда одно, а когда другое использовать...

Grigirii
12.12.2016
13:01:57
если мало и супер параллельно - потоки, если очень очень много (по одному на клиента), то только файбер, тредов много нельзя

Dmitry
12.12.2016
13:03:00
это понятно, не ясно что что именно spawn запускает

Grigirii
12.12.2016
13:03:51
обычный из std.concurency - поток (thread)

fiber стартуется через класс Fiber, либо runTask vibe.d

Dmitry
12.12.2016
13:06:14
Правильно ли я понял, что для средних приложений spawn хватит за глаза?

Google
Dmitry
12.12.2016
13:06:33
Т.е. если мне нужно пустить пару потоков обработки

Grigirii
12.12.2016
13:06:41
да

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

Dmitry
12.12.2016
13:08:27
дык поток и тред это одно и тоже вроде

Grigirii
12.12.2016
13:08:31
да

Admin
ERROR: S client not available

Dmitry
12.12.2016
13:09:32
Просто я смысл фразы не совсем понял. "так что для средних тулов лучше треды" == "так что для средних тулов лучше spawn" ?

Grigirii
12.12.2016
13:10:21
я переформулировал ту же самую фразу, так что ответ всё тот же, да юзай потоки==треды для средних утилит

Dmitry
12.12.2016
13:12:50
Так, а как мне сэмитировать запуск нескольких тысяч потоков? import std.stdio; import std.concurrency; import core.thread; import std.range; void main() { int x = 1000; foreach(i; 0 .. x) { writeln(i); spawn(&worker); } } void worker() { Thread.sleep(1.seconds); writeln("Sleep"); } сейчас получается у меня поток же только один раз стартует?

Grigirii
12.12.2016
13:13:35
запускаются все, просто ты их не дожидаешься и выходишь

там ещё join нужен, чтобы дождаться

https://dlang.org/phobos/core_thread.html#.thread_joinAll

Dmitry
12.12.2016
13:15:00
просто: thread_joinAll(); вызывать?

Grigirii
12.12.2016
13:15:26
можешь попробовать в конец мейна вставить, но я не пробовал сам. я обычно сохраняю все объекты тредов и снова циклом по ним бегаю

Dmitry
12.12.2016
13:16:05
ничего не изменилось... так же работает

Ох... долго читал документацию. Как я понимаю task все же более низкоуровневый механизм и следует все же конкаренси использовать т.е. spawn если нет точного понимания как управлять потокам выполенения

Может я конечно ошибаюсь, а может Али сам не очень точно понимает разницу т.к. меня смущает фраза: "The main difference between a thread that is started with spawn() and a thread that is started with task() is the fact that spawn() makes it possible for threads to send messages to each other."

окей, а нафига тогда таски нужны если spawn делает тоже самое только добавляет сюда механизм обмена сообщениями. Тут явно что-то более глубокое...

Вот еще что нашел про std.concurrency: "The real 1:1 OS thread. There was talk of using green threads for std.concurrency but it's not happening in the near future. — Dmitry Olshansky"

Как я понимаю тут проблема еще с многоядерностью начинается т.е. на одном ядре потоки быстро могут перекидываться сообщениями, а когда они на разных запущены это многократно усложняется все (тем более если есть общие данные). Так что лучше пускать spawn и надеяться что планировщик (в данном случае все же планировщик самой ОС т.к. в основе лежат системные потоки) как-то раскидает все по ядрам

Google
Dmitry
12.12.2016
15:49:35
Можно ли следующий код как-то покрасивее записать? http://pastie.org/pastes/10981743/text

немного смущает передача `ownerTid.send(-1);`как статуса завершения. Это нормальная практика?

И вот этот кусок: if (result == -1) { isDone = true; } можно как-то более компактно все записать?

Pavel
12.12.2016
15:56:07
isDone = result == -1;

Dmitry
12.12.2016
16:16:11
А в мой код можно как-то добавить https://dlang.org/phobos/std_concurrency.html#.OwnerTerminated ? Просто судя по описанию он работает только с receive

http://autodeskbionano.blogspot.ru/2016/12/a-look-at-web-assembly-and-molecular.html по идее DCV должно будет легко скомпилироват т.к. оно без DRuntime идет

А значит CV можно будет получить прямо в браузере)

Pavel
13.12.2016
17:07:34
О, а уже скоро выйдет webassembly ?

Dmitry
13.12.2016
17:18:08
Да в марте релиз

Pavel
13.12.2016
17:37:26
? даже не верится

Вроде года полтора-два назад еще я читал о нем

И говорили что как-то это слишком титанически чтобы быть правдой.

Dmitry
14.12.2016
09:23:23
А как найти дырку в линейном массиве? Типа 1 2 3 5. Что типа четверка отсутствует

Есть какое то красивое решение?

Oleg
14.12.2016
09:26:35
красивое это быстрее n?

тебе нужно факт наличия или что и на какой позиции тоже?

Страница 110 из 719