D-Bus

D-Bus
ТипIPC
РозробникFreedesktop.org
Стабільний випуск1.14.0[1] (28 лютого 2022; 2 роки тому (2022-02-28))
Операційна системабагатоплатформовий
Мова програмуванняC
ЛіцензіяGPL 2+ або AFL[en] 2.1
Репозиторійgitlab.freedesktop.org/dbus/dbus.git
Вебсайтwww.freedesktop.org

D-Bus — система міжпроцесної комунікації, яка дозволяє застосункам в операційній системі спілкуватися один з одним.

D-Bus є частиною проєкту freedesktop.org. Вона має високу швидкість роботи, не залежить від робочого середовища, працює на POSIX-сумісних операційних системах. Також існує версія для Windows (поки що на стадії розробки). Складається з двох частин: демона і низькорівневого API. Існують високорівневі бібліотеки для фреймворків Qt, Java, GLib, C#, Python і бібліотека для C++.

Передумови створення

Програми одного середовища робочого столу можуть тісно взаємодіяти між собою. У графічному середовищі KDE для цього не так давно використовувався DCOP, але інші настільні середовища (наприклад, GNOME) не мали аналогічних систем.

Існувала можливість комунікації у вигляді CORBA, SOAP або XML-RPC, але CORBA використовує велику кількість ресурсів (KDE і GNOME пройшли етап його використання за час свого існування), а SOAP і XML-RPC призначені для вебсервісів.

Раніше GNOME використовував Bonobo, заснований на CORBA, але через залежність від GObject, Bonobo не використовувався в інших робочих середовищах, а низька швидкодія CORBA позначалося на швидкості всього середовища.

Потрібно було організувати обмін повідомленнями між застосунками двох різних середовищ. Для вирішення цього завдання і був створений проєкт D-Bus. Реалізація виявилася вдалою і згодом було вирішено проєкт KDE 4 перевести на використання D-Bus.

Принципи роботи

D-Bus надає системі декілька шин:

  1. Системна шина. Створюється при старті демона D-BUS. З її допомогою відбувається спілкування різних демонів, вона практично недоступна для застосунків користувача.
  2. Сесійна шина. Створюється для користувача, авторизованого в системі. Для кожної такої шини запускається окрема копія демона, за допомогою неї будуть спілкуватися програми, з якими працює користувач.

Кожне повідомлення D-BUS, передане по шині, має свого відправника і свого одержувача, їхні адреси називаються шляхами об'єктів, оскільки D-BUS припускає, що кожен застосунок складається з набору об'єктів, а повідомлення пересилаються не між застосунками, а між об'єктами цих самих застосунків.

Кожен об'єкт може підтримувати один або більше інтерфейсів, які представлені тут у вигляді іменованих груп методів і сигналів — аналогічно інтерфейсам Glib, Qt або Java.

D-BUS також передбачає концепцію сервісів. Сервіс — унікальне місце розташування застосунків на шині. При запуску програма реєструє один або кілька сервісів, якими вона буде володіти доти, поки самостійно не звільнить. До цього моменту жоден застосунок, що претендує на той же сервіс, зайняти його не зможе. Іменуються сервіси аналогічно інтерфейсам.

Сервіси роблять доступною ще одну функцію — запуск необхідних програм у разі надходження до них повідомлень. Для цього повинна бути включена автоактивація, а в конфігурації D-BUS за цим сервісом має бути закріпленим один застосунок. Тоді D-BUS зможе його запустити при появі повідомлення.

Після закриття програми асоційовані сервіси також реконструюються, а D-BUS посилає сигнал про те, що сервіс закритий. Інші програми можуть отримувати такі сигнали і відповідним чином реагувати.

Після підключення до шини застосунок повинен вказати, які повідомлення він бажає отримувати, шляхом додавання масок збігів (matchers). Маски є наборами правил для повідомлень, які будуть доставлятися застосунком, фільтрація може ґрунтуватися на інтерфейсах, шляхах об'єктів і методах. Таким чином, застосунки будуть отримувати лише те, що їм необхідно, проблеми доставки в цьому випадку бере на себе D-BUS.

Повідомлення в D-BUS бувають чотирьох видів: виклики методів, результати викликів методів, сигнали і помилки. Перші призначені для виконання методів над об'єктами, підключеними до D-BUS. Посилаючи таке повідомлення, ви даєте об'єкту завдання, а після його обробки він зобов'язаний повернути вам або результат виклику, або помилку — через повідомлення відповідних типів. Сигнальні повідомлення, як і належить, не беруть до уваги дії об'єктів, оскільки ті можуть сприймати їх як завгодно (або ж не отримувати взагалі).

Щоб повідомлення досягло певного об'єкту, потрібен спосіб послатися на об'єкт. У багатьох мовах програмування це реалізується за допомогою вказівників. Однак вони реалізуються як адреси пам'яті, прив'язані до локального адресного простору програми, і не можуть бути передані від одного застосунку іншому.

Тому в D-Bus кожен об'єкт має своє, унікальне ім'я, яке виглядає як шлях у файловій системі. Наприклад, об'єкт може бути іменований /org/kde/kspread/sheets/3/cells/4/5. Звичайно, найкращими є ті імена, які несуть якесь смислове навантаження, тим не менш, розробники можуть вибрати і таке /com/mycompany/c5yo817y0c1y1c5b, якщо в цьому є певний сенс.

Імена об'єктів лежать у просторах імен, щоб забезпечити розмежування різних програмних модулів. До них зазвичай додається префікс, специфічний для розробника, наприклад /org/kde.

kdbus: реалізація на рівні ядра

З 2010 року зусиллями компанії Collabora[2] і Грега Кроа-Гартмана (Greg Kroah-Hartman), одного з провідних мейнтейнерів ядра Лінукс, розробляється kdbus — надійна, швидка і безпечна система обміну повідомленнями, що підтримує доставку повідомлень як в мультикаст-режимі (від одного відправника до групи одержувачів), так і в режимі точка-точка. Kdbus може використовуватися як відокремлено, наприклад, ця система вже підтримується у systemd, так і для створення реалізації D-Bus, що не вимагає запуску окремого демона в просторі користувача.

З основних переваг реалізації шини kdbus на рівні ядра зазначається[3]:

  • Висока продуктивність за рахунок мінімізації перемикання контексту процесів, меншого виконання операцій копіювання, скорочення системних викликів, використання memfd;
  • Висока безпека через виключення впливу користувацьких процесів на вміст шини і використання механізмів ядра для управління передачею даних, у тому числі з можливістю контролю з боку модулів LSM;
  • До повідомлень може бути прикріплено більше метаданих;
  • Придатність для застосунків, що обробляють великі потоки даних, з можливістю розстановки повідомлень в черзі на підставі пріоритетів та завдання глобального впорядкування повідомлень. Наприклад, деякі розробники знайшли застосування в kdbus навіть для передачі звуку в системі;
  • Несхильність багатьом станам гонитви, які важко усунути в реалізації на рівні користувача. Наприклад, ситуація від'єднання клієнта від шини тільки за умови відсутності повідомлень у його черзі;
  • Можливість моніторингу на рівні ядра. Привілейовані користувачі можуть підключити до потоку повідомлень без створення спеціалізованих механізмів у просторі користувача;
  • Можливість прямої доставки повідомлення без постановки у чергу, що зручно при організації обробки запитів активації по шині;
  • Можливість раннього доступу до шини, на етапі виконання [4].

Дивись також

Примітки

  1. dbus 1.14.2. 10 листопада 2014. Архів оригіналу за 28 лютого 2022. Процитовано 24 листопада 2014.
  2. Представлена реализация шины D-Bus, работающая на уровне Linux-ядра. Архів оригіналу за 29 листопада 2014. Процитовано 24 листопада 2014.
  3. Представлена обновлённая реализация kdbus для ядра Linux. Архів оригіналу за 29 листопада 2014. Процитовано 24 листопада 2014.
  4. initrd

Джерело

Посилання