D-Bus là gì? Kiến trúc giao tiếp giữa các tiến trình trên Linux

D-Bus là gì? Kiến trúc giao tiếp giữa các tiến trình trên Linux

D-Bus là gì? D-Bus là hệ thống giao tiếp giữa các tiến trình (IPC) phổ biến nhất trên Linux, dùng để truyền tin nhắn giữa các ứng dụng và dịch vụ chạy nền. Chính xác hơn, D-Bus đóng vai trò lớp trung gian: các tiến trình không nói chuyện trực tiếp với nhau mà gửi thông điệp qua một tiến trình trung tâm gọi là message bus. Nhờ đó, một chương trình nhỏ như trình gửi tin có thể điều khiển trình phát nhạc, đọc trạng thái pin laptop hay thao tác cài đặt hệ thống mà không cần biết chi tiết bên trong của chúng.

Kiến trúc D-Bus: các tiến trình giao tiếp qua message bus trung gian bằng giao thức D-Bus qua unix domain socket

Ba tầng kiến trúc

Theo hướng dẫn chính thức, D-Bus có ba tầng được xếp chồng lên nhau, mỗi tầng phục vụ một nhóm người dùng khác nhau.

Tầng Thành phần Ai nên dùng
Thư viện lõi libdbus Tác giả binding, xử lý kết nối một-một và wire protocol
Bus daemon dbus-daemon Định tuyến thông điệp từ ứng dụng tới ứng dụng khác
Binding cao cấp GLib, Qt, Python, GObject introspection Đa số lập trình viên ứng dụng

Điểm cần nhấn mạnh: libdbus chỉ hỗ trợ kết nối một-một, giống hệt một socket mạng thô. Chính dbus-daemon mới là thứ biến những kết nối point-to-point đó thành một hệ thống message bus nhiều người nghe.

Hai loại bus riêng biệt

D-Bus có hai bus độc lập, phục vụ hai phạm vi khác nhau:

  • System bus: thông điệp giữa các dịch vụ hệ thống và các tiến trình khác, ví dụ NetworkManager, systemd, logind hay cơ chế cập nhật gói. Mọi ứng dụng trên máy đều gửi tới bus này được.
  • Session bus: thông điệp giữa các ứng dụng trong phiên đồ hoạ của một người dùng, ví dụ trình duyệt báo trạng thái tải trang, trình phát nhạc phát sự kiện đổi bài, ứng dụng trên điện thoại gửi lệnh tới desktop.

Ranh giới này là điều kiện an toàn quan trọng: một ứng dụng bình thường không nên tự ý đăng ký service trên system bus, vì đó là phạm vi dành cho phần mềm hệ thống chạy với quyền quản trị.

Sơ đồ nhiều tiến trình Linux giao tiếp với nhau qua D-Bus thay vì socket trực tiếp

Các khái niệm cốt lõi

Object Path, Interface và Bus Name

Trong D-Bus, mọi thứ được định danh theo chuỗi văn bản theo kiểu đường dẫn:

  • Object Path: định danh một đối tượng, ví dụ /org/freedesktop/NetworkManager.
  • Interface: nhóm các phương thức và tín hiệu mà một đối tượng cung cấp, ví dụ org.freedesktop.DBus.Properties cho đọc-ghi thuộc tính.
  • Bus Name: tên mà một tiến trình đăng ký để các tiến trình khác tìm thấy nó. Tên thường có dạng ngược tên miền như org.freedesktop.NetworkManager.

Ba loại thông điệp

Trao đổi qua D-Bus dựa trên ba loại thông điệp, mỗi loại có ngữ nghĩa khác nhau:

  • Method call: yêu cầu có phản hồi, giống hàm có giá trị trả về. Client gửi lời gọi và chờ reply.
  • Signal: thông báo một chiều, không có phản hồi, giống sự kiện. Nhiều tiến trình có thể cùng nghe một signal.
  • Error reply: phản hồi báo lỗi cho một method call, mang theo tên lỗi theo quy ước.

Introspection: tự mô tả

Đây là một trong những tính năng hay nhất của D-Bus. Khi một client hỏi một service về interface của nó, service trả lời bằng XML mô tả đầy đủ danh sách method, signal và thuộc tính. Nhờ cơ chế này, công cụ như gdbus hay các thư viện binding có thể tự sinh lớp proxy mà không cần người viết code biết trước giao diện. Đây cũng là cơ sở để tiện ích có thể chẩn đoán được vấn đề chỉ bằng cách đọc XML trả về.

D-Bus và cgroups: hai tầng kiểm soát

Một điểm mà người mới hay nhầm: D-Bus và hệ thống cgroups là hai lớp kiểm soát khác nhau, không thay thế cho nhau. systemd sử dụng cả hai. D-Bus cung cấp API quản lý để các công cụ khác điều khiển systemd từ xa, còn cgroups ở tầng kernel thực sự giới hạn tài nguyên. Bạn có thể xem toàn bộ cấu trúc D-Bus đang chạy trên máy mình bằng cách liệt kê các bus và các tên đã đăng ký, hoặc theo dõi cây tiến trình và tài nguyên cấp phát cho từng nhóm.

Khi nào nên dùng D-Bus?

D-Bus hợp lý khi bạn cần giao tiếp với một ứng dụng khác đang chạy trên cùng máy mà bạn không muốn phụ thuộc vào chi tiết nội bộ của nó. Ví dụ một ứng dụng media player muốn điều khiển nhạc, hoặc một panel nhỏ muốn theo dõi trạng thái mạng.

Ngược lại, đừng dùng D-Bus làm kênh truyền dữ liệu lớn. D-Bus được thiết kế cho thông điệp nhỏ, điều khiển và sự kiện. Nếu cần truyền hàng trăm megabyte, hãy dùng socket trực tiếp hoặc chia sẻ tệp. Đồng thời, mọi thông điệp phải có kiểu dữ liệu cụ thể: D-Bus không phải nơi chứa dữ liệu tùy ý không kiểm soát, vì bất kỳ ứng dụng nào trên phiên đều có thể nghe thấy.

Đặc tả đầy đủ, bao gồm định dạng wire protocol và quy tắc đặt tên, được công bố tại dbus.freedesktop.org. Đây là tài liệu bắt buộc đọc nếu bạn định viết binding riêng thay vì dùng GLib hay Qt.

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

CRDT là gì? Cấu trúc dữ liệu hội tụ không xung đột

CRDT là gì? Kiểu dữ liệu hội tụ không xung đột Conflict-free Replicated Data Type (CRDT) là cấu trúc dữ liệu được thiết kế để sao chép trên nhiều nút…

Xem thêm

OpenGL là gì? Kiến trúc đồ họa và pipeline dựng hình trên GPU

OpenGL là gì? Kiến trúc đồ họa và pipeline dựng hình OpenGL (Open Graphics Library) là chuẩn API đa nền tảng để vẽ đồ họa hai chiều và ba chiều,…

Xem thêm

Huffman coding là gì? Thuật toán nén dữ liệu theo tần suất ký tự

Huffman coding là gì? Thuật toán nén dữ liệu theo tần suất ký tự Sơ đồ cây Huffman dựng từ tần suất bốn ký tự, mỗi lá là một ký…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất