Как стать автором
Обновить

Комментарии 29

НЛО прилетело и опубликовало эту надпись здесь
К сожалению не могу ответить на этот вопрос, я пользуюсь vim, под него есть хороший плагин dutyl, он использует DCD для автодополнения и поиска документации, dub для выяснения путей, dfmt для форматирования кода, DScanner для проверки синтаксиса, то есть по сути полный фарш (правда, dfmt у меня не завёлся ровно).
НЛО прилетело и опубликовало эту надпись здесь
Порой мне кажется, что серьёзным препятствием на пути к широкому применению D является именно отсутствие полноценной IDE.
Не совсем понял проблему. Нужна именно «родная» IDE или достаточно плагина к уже существующей?
Вот нашел плагин для IDEA, она уж точно полноценная IDE.
Не пользовался, но оно есть в виде плагина для qtcreator.
Ещё на вики dlang есть список плагинов (по всей видимости не полный).
Для винды Visual Studio + VisualD
Для линукса по всей видимости Eclipse + DDT
Под виндой пользуюсь Mono-D — очень нравится, но под виндой отладчик с пятой версией Xamarin Studio не работает, только с четвёртой (и вроде разработчик Mono-D не собирается это исправлять в каком-то ближайшем будущем). Для D у меня это основная среда разработки. Иногда также использую Visual-D.
НЛО прилетело и опубликовало эту надпись здесь
Вы не совсем правильно поняли. Если Вам нужны указатели, просто используйте их как Вам угодно: с арифметикой, приведением одних типов указателей к другим и т.д. SafeD это только подмножество языка, включаемое атрибутом @​safe, то есть Вы намерено декларируете в коде, что хотите его использовать и декларируете участок, где оно должно использоваться. Это может быть либо личным желанием оградить себя от ошибок работы с памятью, либо требованием к качеству ПО.
Прекрасно D работает с указателе. Другое дело, что можно включить режим мешающий «стрелять себе по ногам», в нем с указателями нельзя :)
НЛО прилетело и опубликовало эту надпись здесь
Как-то сумбурно, новичок не поймёт. Особенно про многопоточность. Кроме того, тема передачи сообщений не раскрыта. Зачем использовать свой опасный неудобный велосипед, если есть стандартные удобные средства обмена сообщениями?
Новичок в программировании != новичок в D. Я ставил целью разъяснить некоторые моменты людям, знакомым с программированием, но не знакомыми с D. Насчёт велосипедов. Я пробовал организовывать этими стандартными средствами сложные очереди, где одни сообщения должны отрабатываться гарантировано, другие пропускаться по истечению срока, третие идут в обратном направлении и так далее. И понял, что через std.concurrency сложные вещи делать реально сложно. Проще создать несколько очередей (в одном разделяемом объекте) и по ним пускать разные сообщения, а в std.concurrency я не нашёл способа создания нескольких очередей. Соответственно, в простых ситуациях всё что я описал не нужно. Тут же возникает вопрос, чем опасен подход, который я описал и какой конкретно аспект вопроса не расскрыт? Synchronized самостоятельно разруливает синхронизацию каждого метода, immutable объекты нельзя изменять, в разных потока их использовать безопасно, можно это дело сломать, конечно, с помощью cast, но это уже будет на Вашей совести.
И всё же тема сложная, её не уместить в короткую статью.

Что же вы такое сложное делали, что сообщений вам не хватило?

Опасен он прежде всего возможными взаимоблокировками.
При вызове какого либо метода блокируется весь объект, а не метод, так как у всех методов один обеъкт синхронизации, так что методы могут быть вызваны только последовательно. Он с этой стороны не опасен, а не производителен.
Пока объект один — да. Даже когда объектов несколько, но используют один мьютекс — тоже да. Но стоит появиться двум объектам с разными мьютексами, то привет взаимоблокировкам. Эта палка может и не выстрелить, конечно, но направлять в людей всё же не стоит :-)

Касательно производительности — подозреваю передача сообщений реализована через CAS, что куда эффективней.
Чтобы получить состояние взаимоблокировки нужно использовать вложенные блоки synchronized, если Вам нужно заблокировать несколько mutex'ов их нужно использовать в одном блоке синхронизации. Использование в одном блоке безопасно, так как действительный порядок блокировки не зависит от порядка написания объектов синхронизации и он всегда будет одинаков. То есть, если в одном блоке сначала блокируется A а затем B, то и в других блоках этот порядок сохранится. Начёт передачи сообщений вы заблуждаетесь через CAS, в std.concurrency используются для этого обычная схема с блокировками. И если честно не совсем представляю как можно для этого использовать CAS, было бы не плохо, если бы Вы привели пример.
Вот именно, что нужно быть очень аккуратным и вызывая функцию проверить все функции, которые та явно или косвенно вызывает, и взять все необходимые блокировки заранее все разом.

Печально, я надеялся там додумались реализовать обмен сообщениями без блокировок. Например — статья про неблокирующие очереди.
Не совсем понял аргумент. Если мы говорим про многопоточное программирование с блокировками в общем, то оно само по себе не является простым занятием. Передача сообщений это лишь способ снижения сложности, а конкретней, способ уйти от таких взаимоблокирующих вызовов. Многопоточное программирование без блокировок ещё более сложная задача, что подтверждает Ваш пример (кстати, весьма познавательный). Да и нет у него особой специфики в D. Та же самая функция cas и все те же проблемы, что и, например, в С++. А от велосипедов уйти никогда не удасться на 100%, так как std.concurrency не может покрыть все задачи, а реализовывать непокрытые как-то нужно. Поход, описанный мной, показывает только особенности способа создания очереди сообщений именно в D. Я не говорил, что надо делать всегда именно так. Выбор всегда остаётся за програмистом.
Я тут поигрался с потоками. Для передачи сообщений между ними можно даже без CAS обойтись — достаточно иметь по очереди между каждой парой потоков, где один только пишет, а другой только читает, сохраняя инвариант «В очереди всегда есть как минимум одно сообщение». Небольшой пример. Тут нет поддержки произвольных типов сообщений и соответственно паттерн-матчинга. Также нет ограничения на размер почтового ящика, приоритетов и протухания, но это всё легко прикручивается. Также я попробовал сделать синхронным лишь мапку Tid=>Queue, чтобы не париться, оставив саму очередь неблокирующей. Не знаю получилось ли у меня это (пока ещё плохо понимаю типизацию в D). Идея в том, что блокировка нужна лишь при появлении новых потоков и удалении старых, а друг с другом они обмениваются сообщениями без каких-либо блокировок.
На самом деле сейчас может быть я решил бы ту задачу совершенно по другому. Ну а старое решение осталось. Мне нужно было максимально гибко управлять потоками, приостанавливать их деятельность, они обрабатывали данные, которые можно было пропускать по истечению времени, отправляли друг другу сигналы. Вроде справлялось решение с поставленной задачей.
Ну, судя по описанию send-receive с минимальной обёрткой, реализующей протокол поддерживающий таймауты, должны бы подойти идеально.
Кстати, в чём отличие __gshared и shared переменных?
__gshared это полный аналог глобальных перменных из C/C++. В основном __gshared используется для создания обёрток и биндингов. Модификатор shared является частью системы типов D, он транзитивный (если объект shared, значит и все поля его shared), определяет набор операций (у shared объектов можно вызывать только shared методы). __gshared не относится к системе типов, и в этом плане не безопасен. Использовать его Вы можете только на свой страх и риск (никаких проверок на наличие синхронизации нет, как в C/C++). С точки зрения доступности данных они эквивалентны. А начинается __gshared с двух подчёркиваний, чтобы легче было искать в коде, когда начнутся проблемы =) В итоге, если Вам не нужно использовать разделяемые глобальные переменные с C/C++ кодом, то по сути нет необходимости использовать __gshared.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации