Разработчик(и) | Красная Шапочка |
---|---|
Первоначальный выпуск | Ноябрь 2006 г ( 2006-11 ) |
Стабильный релиз | 1.14.10 / 1 сентября 2023 г. ( 2023-09-01 ) [1] |
Предварительный релиз | 1.15.8 / 21 августа 2023 г. ( 2023-08-21 ) [2] |
Репозиторий |
|
Написано в | С |
Операционная система | Кроссплатформенный |
Предшественник | CORBA DCOP |
Тип | |
Лицензия | GPLv2+ или AFL 2.1 [3] |
Веб-сайт | www.freedesktop.org/wiki/Software/dbus |
D-Bus (сокращение от « Desktop Bus » [4] ) — это механизм промежуточного программного обеспечения, ориентированный на сообщения , который обеспечивает связь между несколькими процессами, работающими одновременно на одной машине. [5] [6] D-Bus был разработан как часть проекта freedesktop.org , инициированного разработчиком GNOME Хавоком Пеннингтоном для стандартизации служб, предоставляемых средами рабочего стола Linux, такими как GNOME и KDE . [7] [8] [ нерабочая ссылка ]
Проект freedesktop.org также разработал свободную и открытую программную библиотеку под названием libdbus, как эталонную реализацию спецификации. Эта библиотека не является самим D-Bus, поскольку существуют и другие реализации спецификации D-Bus, такие как GDBus (GNOME), [9] QtDBus ( Qt /KDE), [10] dbus-java [11] и sd-bus (часть systemd ). [12]
D-Bus — это механизм межпроцессного взаимодействия (IPC), изначально разработанный для замены систем взаимодействия программных компонентов , используемых в средах рабочего стола GNOME и KDE Linux ( CORBA и DCOP соответственно). [13] [14] Компоненты этих сред рабочего стола обычно распределены по многим процессам, каждый из которых предоставляет только несколько — обычно одну — служб . Эти службы могут использоваться обычными клиентскими приложениями или другими компонентами среды рабочего стола для выполнения своих задач. [15]
D-Bus обеспечивает абстракцию программной шины , которая собирает все коммуникации между группой процессов по одному общему виртуальному каналу. [6] Процессы, подключенные к шине, не знают, как она реализована внутри, но спецификация D-Bus гарантирует, что все процессы, подключенные к шине, могут общаться друг с другом через нее. D-Bus несет как минимум 2,5-кратную потерю производительности по сравнению с IPC один к одному. [16]
Среды рабочего стола Linux используют возможности D-Bus, создавая экземпляры нескольких шин, в частности: [17] [6] [18]
Процесс может подключаться к любому количеству шин, при условии, что ему предоставлен доступ к ним. На практике это означает, что любой пользовательский процесс может подключаться к системной шине и к своей текущей шине сеанса, но не к шинам сеансов другого пользователя или даже к другой шине сеанса, принадлежащей тому же пользователю. Последнее ограничение может измениться в будущем, если все пользовательские сеансы будут объединены в одну пользовательскую шину. [19]
D-Bus предоставляет дополнительные или упрощает существующие функции для приложений, включая обмен информацией, модульность и разделение привилегий . Например, информация о входящем голосовом вызове, полученном через Bluetooth или Skype, может распространяться и интерпретироваться любым работающим в данный момент музыкальным проигрывателем, который может реагировать отключением звука или приостановкой воспроизведения до завершения вызова. [20]
D-Bus также может использоваться в качестве фреймворка для интеграции различных компонентов пользовательского приложения. Например, офисный пакет может взаимодействовать через шину сеанса для обмена данными между текстовым процессором и электронной таблицей .
Каждое подключение к шине идентифицируется в контексте D-Bus тем, что называется именем шины . [5] Имя шины состоит из двух или более строк букв, цифр, тире и подчеркиваний, разделенных точками — обратное доменное имя . Примером допустимого имени шины является org.freedesktop.NetworkManager
. [6]
Когда процесс устанавливает соединение с шиной, шина назначает соединению специальное имя шины, называемое уникальным именем соединения . [18] [6] Имена шин такого типа являются неизменяемыми — гарантируется, что они не изменятся, пока существует соединение, — и, что более важно, их нельзя повторно использовать в течение срока службы шины. [5] [18] [ 6] Это означает, что никакое другое соединение с этой шиной никогда не будет иметь такого уникального имени соединения, даже если тот же процесс закроет соединение с шиной и создаст новое. Уникальные имена соединений легко распознаются, поскольку они начинаются с запрещенного в противном случае символа двоеточия. [18] [6] Примером уникального имени соединения является :1.1553
(символы после двоеточия не имеют особого значения [18] ).
Процесс может запросить дополнительные имена шин для своего соединения, [18] при условии, что любое запрошенное имя уже не используется другим соединением с шиной. На языке D-Bus, когда имя шины назначается соединению, говорят, что соединение владеет именем шины. [5] [18] В этом смысле имя шины не может принадлежать двум соединениям одновременно, но, в отличие от уникальных имен соединений, эти имена могут быть повторно использованы, если они доступны: процесс может вернуть себе имя шины, освобожденное — намеренно или нет — другим процессом. [5] [6]
Идея, лежащая в основе этих дополнительных имен шин, обычно называемых общеизвестными именами , заключается в предоставлении способа ссылаться на службу с использованием заранее подготовленного имени шины. [18] [6] Например, служба, которая сообщает текущее время и дату в системной шине, находится в процессе, соединение которого владеет именем шины org.freedesktop.timedate1 , независимо от того, какой это процесс.
Имена шин можно использовать как простой способ реализации приложений с одним экземпляром (вторые экземпляры обнаруживают, что имя шины уже занято). [18] Его также можно использовать для отслеживания жизненного цикла процесса обслуживания, поскольку шина отправляет уведомление, когда имя шины освобождается из-за завершения процесса. [18]
Из-за своей первоначальной концепции как замены нескольких компонентно-ориентированных систем связи, D-Bus разделяет со своими предшественниками объектную модель, в которой выражается семантика коммуникаций между клиентами и службами. Термины, используемые в объектной модели D-Bus, имитируют термины, используемые в некоторых объектно-ориентированных языках программирования . Это не означает, что D-Bus каким-то образом ограничен языками ООП — на самом деле, наиболее используемая реализация ( libdbus ) написана на языке C , процедурном языке программирования .
В D-Bus процесс предлагает свои услуги, предоставляя объекты . Эти объекты имеют методы , которые могут быть вызваны, и сигналы , которые объект может испускать. [18] Методы и сигналы совместно называются членами объекта . [5] Любой клиент, подключенный к шине, может взаимодействовать с объектом, используя его методы, делая запросы или командуя объекту выполнять действия. [18] Например, объект, представляющий службу времени, может быть запрошен клиентом с помощью метода, который возвращает текущую дату и время. Клиент также может прослушивать сигналы, которые испускает объект, когда его состояние изменяется из-за определенных событий, обычно связанных с базовой службой. Примером может служить ситуация, когда служба, управляющая аппаратными устройствами, такими как USB или сетевые драйверы, сигнализирует о событии «добавлено новое аппаратное устройство». Клиенты должны сообщить шине, что они заинтересованы в получении определенных сигналов от определенного объекта, поскольку шина D-Bus передает сигналы только тем процессам, у которых зарегистрирован интерес к ним. [6]
Процесс, подключенный к шине D-Bus, может запросить экспортировать столько объектов D-Bus, сколько захочет. Каждый объект идентифицируется путем к объекту , строкой цифр, букв и подчеркиваний, разделенных и префиксированных символом косой черты, называемым так из-за их сходства с путями файловой системы Unix . [5] [18] Путь к объекту выбирается запрашивающим процессом и должен быть уникальным в контексте этого подключения к шине. Примером допустимого пути к объекту является /org/kde/kspread/sheets/3/cells/4/5
. [18] Однако не обязательно — но и не рекомендуется — формировать иерархии внутри путей к объектам. [6] Конкретное соглашение об именовании объектов службы полностью зависит от разработчиков такой службы, но многие разработчики предпочитают создавать для них пространство имен, используя зарезервированное доменное имя проекта в качестве префикса (например, /org/kde ). [18]
Каждый объект неразрывно связан с определенным шинным соединением, куда он был экспортирован, и, с точки зрения D-Bus, существует только в контексте такого соединения. Поэтому, чтобы иметь возможность использовать определенную службу, клиент должен указать не только путь объекта, предоставляющего желаемую службу, но и имя шины, под которым процесс службы подключен к шине. [5] Это, в свою очередь, позволяет нескольким процессам, подключенным к шине, экспортировать разные объекты с идентичными путями объектов однозначно.
Интерфейс определяет элементы — методы и сигналы — которые могут использоваться с объектом. [18] Это набор объявлений методов (включая его передаваемые и возвращаемые параметры) и сигналов (включая его параметры), идентифицированных именем, разделенным точкой, напоминающим нотацию интерфейсов языка Java . [18] [6] Примером допустимого имени интерфейса является . [6] Несмотря на их сходство, имена интерфейсов и имена шин не следует путать. Объект D-Bus может реализовывать несколько интерфейсов, но по крайней мере должен реализовывать один, обеспечивая поддержку для каждого метода и сигнала, определенных им. Комбинация всех интерфейсов, реализованных объектом, называется типом объекта . [5] [18]org.freedesktop.Introspectable
При использовании объекта хорошей практикой для клиентского процесса является предоставление имени интерфейса члена помимо имени члена, но это обязательно только в случае неоднозначности, вызванной дублированием имен членов, доступных из разных интерфейсов, реализованных объектом [5] [18] — в противном случае выбранный член не определен или ошибочен. С другой стороны, излучаемый сигнал всегда должен указывать, к какому интерфейсу он принадлежит.
Спецификация D-Bus также определяет несколько стандартных интерфейсов, которые объекты могут захотеть реализовать в дополнение к своим собственным интерфейсам. [17] Хотя технически это необязательно, большинство разработчиков служб D-Bus предпочитают поддерживать их в своих экспортируемых объектах, поскольку они предлагают важные дополнительные функции клиентам D-Bus, такие как интроспекция . [6] Эти стандартные интерфейсы: [17] [6]
Спецификация D-Bus определяет ряд административных операций шины (называемых «службами шины»), которые должны выполняться с использованием объекта /org/freedesktop/DBus , который находится в имени шины org.freedesktop.DBus . [17] Каждая шина резервирует это специальное имя шины для себя и управляет любыми запросами, сделанными специально для этой комбинации имени шины и пути объекта. Административные операции, предоставляемые шиной, определяются интерфейсом объекта org.freedesktop.DBus . Эти операции используются, например, для предоставления информации о состоянии шины [5] или для управления запросом и освобождением дополнительных известных имен шины. [17] [6]
D-Bus был задуман как общая, высокоуровневая система межпроцессного взаимодействия. Для достижения таких целей коммуникации D-Bus основаны на обмене сообщениями между процессами, а не на «сырых байтах». [5] [18] Сообщения D-Bus представляют собой высокоуровневые дискретные элементы, которые процесс может отправлять через шину другому подключенному процессу. Сообщения имеют четко определенную структуру (даже типы данных, передаваемых в их полезной нагрузке, определены), что позволяет шине проверять их и отклонять любые неправильно сформированные сообщения. В этом отношении D-Bus ближе к механизму RPC , чем к классическому механизму IPC, со своей собственной системой определения типов и собственным маршалингом . [5]
Шина поддерживает два режима обмена сообщениями между клиентом и процессом обслуживания [5] :
Каждое сообщение D-Bus состоит из заголовка и тела. [18] Заголовок формируется несколькими полями, которые идентифицируют тип сообщения, отправителя, а также информацию, необходимую для доставки сообщения получателю (имя шины назначения, путь объекта, имя метода или сигнала, имя интерфейса и т. д.). [18] [17] Тело содержит полезную нагрузку данных, которую интерпретирует процесс-получатель, например, входные или выходные аргументы. Все данные кодируются в хорошо известном двоичном формате, называемом форматом провода , который поддерживает сериализацию различных типов, таких как целые числа и числа с плавающей точкой, строки, составные типы и т. д., [17] также называемом маршалингом .
Спецификация D-Bus определяет протокол проводов : как создавать сообщения D-Bus для обмена между процессами в рамках соединения D-Bus. Однако она не определяет базовый метод транспортировки для доставки этих сообщений.
Большинство существующих реализаций D-Bus следуют архитектуре эталонной реализации. Эта архитектура состоит из двух основных компонентов: [5]
Библиотека libdbus (или ее эквивалент) внутренне использует собственный механизм IPC нижнего уровня для передачи требуемых сообщений D-Bus между двумя процессами на обоих концах соединения D-Bus. Спецификация D-Bus не предписывает, какие конкретные транспортные механизмы IPC должны быть доступны для использования, поскольку именно библиотека коммуникаций решает, какие транспортные методы она поддерживает. Например, в операционных системах типа Unix, таких как Linux, libdbus обычно использует сокеты домена Unix в качестве базового транспортного метода, но также поддерживает сокеты TCP . [5] [18]
Библиотеки связи обоих процессов должны согласовать выбранный метод транспортировки, а также конкретный канал, используемый для их связи. Эта информация определяется тем, что D-Bus называет адресом . [ 6] [18] Сокеты домена Unix являются объектами файловой системы , и поэтому их можно идентифицировать по имени файла, поэтому допустимым адресом будет unix:path=/tmp/.hiddensocket
. [5] [17] Оба процесса должны передать один и тот же адрес своим соответствующим библиотекам связи, чтобы установить соединение D-Bus между ними. Адрес также может предоставлять дополнительные данные библиотеке связи в виде key=value
пар, разделенных запятыми. [6] [17] Таким образом, например, он может предоставлять информацию об аутентификации для определенного типа соединения, которое его поддерживает.
Когда демон шины сообщений, такой как dbus-daemon, используется для реализации шины D-Bus, все процессы, которые хотят подключиться к шине, должны знать адрес шины , адрес, по которому процесс может установить соединение D-Bus с центральным процессом шины сообщений. [5] [18] В этом сценарии демон шины сообщений выбирает адрес шины, а остальные процессы должны передать это значение в свои соответствующие библиотеки libdbus или эквивалентные библиотеки. dbus-daemon определяет другой адрес шины для каждого экземпляра шины, который он предоставляет. Эти адреса определяются в файлах конфигурации демона.
Два процесса могут использовать соединение D-Bus для прямого обмена сообщениями между собой, [22] но это не тот способ, которым обычно предполагается использовать D-Bus. Обычный способ — всегда использовать демон шины сообщений (т. е. dbus -daemon ) в качестве центральной точки связи, с которой каждый процесс должен установить свое соединение D-Bus «точка-точка». Когда процесс — клиент или служба — отправляет сообщение D-Bus, процесс шины сообщений получает его в первую очередь и доставляет соответствующему получателю. Демон шины сообщений можно рассматривать как концентратор или маршрутизатор, отвечающий за доставку каждого сообщения к месту назначения путем его повторения через соединение D-Bus с процессом-получателем. [18] Процесс-получатель определяется именем шины назначения в поле заголовка сообщения, [17] или информацией о подписке на сигналы, поддерживаемой демоном шины сообщений в случае сообщений о распространении сигналов. [6] Демон шины сообщений также может создавать свои собственные сообщения в ответ на определенные условия, такие как сообщение об ошибке для процесса, который отправил сообщение на несуществующее имя шины. [18]
dbus-daemon улучшает набор функций, уже предоставляемых самим D-Bus, с помощью дополнительных функций. Например, активация служб позволяет автоматически запускать службы при необходимости — когда первый запрос к любому имени шины такой службы поступает в демон шины сообщений. [5] Таким образом, процессы служб не должны запускаться во время инициализации системы или стадии инициализации пользователя, и не должны потреблять память или другие ресурсы, когда они не используются. Эта функция изначально была реализована с использованием помощников setuid , [23] но в настоящее время она также может быть предоставлена фреймворком активации служб systemd. [ необходима цитата ] Активация служб является важной функцией, которая облегчает управление жизненным циклом процесса служб (например, когда компонент рабочего стола должен запускаться или останавливаться). [18]
D-Bus был запущен в 2002 году Хавоком Пеннингтоном, Алексом Ларссоном ( Red Hat ) и Андерсом Карлссоном. [8] Версия 1.0, считающаяся стабильной API , была выпущена в ноябре 2006 года. [24] [25]
Находясь под сильным влиянием системы DCOP , используемой версиями 2 и 3 KDE , D-Bus заменил DCOP в выпуске KDE 4. [25] [26] Реализация D-Bus поддерживает большинство операционных систем POSIX , и существует порт для Windows . Он используется Qt 4 и позднее GNOME . В GNOME он постепенно заменил большую часть более раннего механизма Bonobo . Он также используется Xfce .
Одним из первых последователей был (ныне устаревший) Hardware Abstraction Layer . HAL использовал D-Bus для экспорта информации об оборудовании, которое было добавлено или удалено из компьютера. [8]
Использование D-Bus неуклонно расширяется за пределы первоначальной сферы настольных сред, охватывая все большее количество системных служб. Например, сетевой демон NetworkManager , стек Bluetooth BlueZ и звуковой сервер PulseAudio используют D-Bus для предоставления части или всех своих служб. systemd использует протокол проводов D-Bus для связи между systemctl и systemd, а также продвигает традиционные системные демоны в службы D-Bus, такие как logind . [27] Другим активным пользователем D-Bus является Polkit , чей демон полномочий политики реализован как служба, подключенная к системной шине. [28]
Хотя существует несколько реализаций D-Bus, наиболее широко используемой является эталонная реализация libdbus , разработанная тем же проектом freedesktop.org, который разработал спецификацию. Однако libdbus — это низкоуровневая реализация, которая никогда не предназначалась для непосредственного использования разработчиками приложений, а была лишь справочным руководством для других повторных реализаций D-Bus (например, включенных в стандартные библиотеки сред рабочего стола или в привязки языков программирования ). Сам проект freedesktop.org рекомендует авторам приложений «использовать одну из привязок или реализаций более высокого уровня» вместо этого. [29] Преобладание libdbus как наиболее используемой реализации D-Bus привело к тому, что термины «D-Bus» и «libdbus» стали часто использоваться взаимозаменяемо, что привело к путанице. [ необходима цитата ]
GDBus [9] — это реализация D-Bus на основе потоков GIO , включённых в GLib , предназначенная для использования в GTK+ и GNOME . GDBus — это не оболочка libdbus, а полная и независимая переработка спецификации и протокола D-Bus. [30] MATE Desktop [31] и Xfce (версия 4.14), которые также основаны на GTK+ 3, также используют GDBus. [ требуется ссылка ]
В 2013 году проект systemd переписал libdbus в попытке упростить код, [32] но это также привело к значительному увеличению общей производительности D-Bus. В предварительных тестах BMW обнаружила, что библиотека D-Bus systemd увеличила производительность на 360%. [33] В версии 221 systemd , выпущенной в 2015 году, API sd-bus был объявлен стабильным. [34]
kdbus был проектом, нацеленным на повторную реализацию D-Bus в качестве механизма межпроцессного взаимодействия между равноправными процессами, опосредованного ядром . Помимо улучшений производительности, kdbus имел бы преимущества, вытекающие из других функций ядра Linux, таких как пространства имен и аудит, [33] [37] безопасность от посредничества ядра, закрытие условий гонки и возможность использования D-Bus во время загрузки и выключения (по мере необходимости systemd). [38] Включение kdbus в ядро Linux оказалось спорным, [39] и было отклонено в пользу BUS1, как более общего межпроцессного взаимодействия . [40]
Было разработано несколько привязок к языкам программирования для D-Bus, [41] например, для Java , C# , Ruby , Rust и Perl . [ требуется ссылка ]
Одной из важнейших разработок, появившихся в Linux Desktop, является Desktop Bus (D-Bus), система передачи сообщений. D-Bus важна, поскольку она служит механизмом межпроцессного взаимодействия, который позволяет настольным приложениям общаться друг с другом [...].
-Bus [...] предназначен для использования в качестве единого промежуточного уровня под основными бесплатными средами рабочего стола.
Для использования в сеансе рабочего стола рабочие столы GNOME и KDE имеют значительный предыдущий опыт работы с различными решениями IPC, такими как CORBA и DCOP. D-Bus создан на основе этого опыта и тщательно адаптирован для удовлетворения потребностей этих проектов рабочего стола в частности.
-Bus был впервые создан для замены модели компонентов типа CORBA, лежащей в основе среды рабочего стола GNOME. Подобно DCOP (используемой KDE), D-Bus должен стать стандартным компонентом основных свободных сред рабочего стола для GNU/Linux и других платформ.
работаем над тем, чтобы перенести все на настоящую пользовательскую шину, которая будет только одна на пользователя в системе, независимо от того, сколько раз этот пользователь войдет в систему.
Существуют также некоторые повторные реализации протокола D-Bus для таких языков, как C#, Java и Ruby. Они не используют эталонную реализацию libdbus
построен на основе общей структуры передачи сообщений "один к одному", которая может использоваться любыми двумя приложениями для прямого взаимодействия (без использования демона шины сообщений)
момента создания systemd это была система IPC, в которой он предоставлял свои интерфейсы.
Реализация низкого уровня изначально не предназначена для использования авторами приложений. Скорее, это основа для связывания авторов и ссылка для повторных реализаций. Если вы можете это сделать, рекомендуется использовать одну из привязок или реализаций более высокого уровня.
-glib использует реализацию ссылки libdbus, GDBus — нет. Вместо этого он полагается на потоки GIO в качестве транспортного уровня и имеет собственную реализацию для настройки соединения D-Bus и аутентификации.