BeOS: Master of Messaging
While other OSes struggle with basic multitasking, BeOS was designed from the ground up for massive multithreading. The heart of this responsiveness is BMessage. Everything in the Be API revolves around these extensible data containers passed between threads.
Sending a Message
In BeOS, you don't just call a method on a window; you send it a message. This ensures the UI never hangs while waiting for a background task.
#include <Message.h>
#include <Messenger.h>
#include <Window.h>
// Sending a message from a worker thread to a window
void WorkerThread(void *data) {
BMessenger messenger("application/x-vnd.MyApp-MyWindow");
BMessage msg(MSG_UPDATE_DATA);
msg.AddString("status", "Task Complete");
msg.AddInt32("percent", 100);
messenger.SendMessage(&msg);
}
Handling the Message
The target window (or any BHandler) overrides MessageReceived.
void MyWindow::MessageReceived(BMessage *msg) {
switch (msg->what) {
case MSG_UPDATE_DATA: {
const char *status;
int32 percent;
if (msg->FindString("status", &status) == B_OK &&
msg->FindInt32("percent", &percent) == B_OK) {
// Update UI safely on the window thread
fStatusView->SetText(status);
fProgressBar->Update(percent);
}
break;
}
default:
BWindow::MessageReceived(msg);
break;
}
}
The beauty of BMessage is its flexibility. You can bundle anything: strings, ints, colors, even entire BBitmap objects. Because every window runs in its own thread, sending these messages doesn't block your user interface. This is why BeOS R4.5 feels faster on a Pentium 200 than Windows 98 does on a Pentium III.