Windows3.1 的協同式多工系統
1990 年時,微軟為了讓 DOS 上可以執行視窗功能,發展出了早期的 Windows 的系統,為了讓 DOS 的使用者能感覺到視窗系統的好處,微軟將 Windows 3.0 與 Windows 3.1 架構在 DOS 系統上。但由於 DOS 並不支援多工模式,Windows 只好採用一個稱為協同式多工的機制,這其實是一種假的多工機制,要求所有的程式都必須改變寫法,以便在工作進行一小段後就將 CPU 的控制權交還給作業系統,讓作業系統可以將 CPU 切換給其他程式使用,於是,所有的程式就都必須採取類似下列的輪詢式撰寫方法。其中的 while (GetMessage(&msg, NULL, 0, 0)) {} 這一個迴圈就是輪詢迴圈,在利用 GetMessage 函數取得訊息後,隨即利用TranslateMessage 轉換訊息與 DispatchMessage 分派訊息,然後,Windows 系統會在適當時機呼叫 WndProc 函數,以便程式設計師可以處理這些訊息。
//---------------------------------------------------------------
// WinMain - 程式進入點
//---------------------------------------------------------------
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
UNREFERENCED_PARAMETER(lpCmdLine); // 避免編譯時的警告
if (!hPrevInstance)
if (!InitApplication(hInstance))
return (FALSE);
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam); // 傳回PostQuitMessage 的參數
}
//---------------------------------------------------------------
// WndProc - 視窗函式
//---------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message) {
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId) {
case IDM_ABOUT:
DialogBox(_hInst, "AboutBox", hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
// 使用者想結束程式。處理方式與WM_CLOSE 相同。
DestroyWindow (hWnd);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
break;
case WM_DESTROY: // 視窗已經被摧毀(程式即將結束)。
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
一定有細心的讀者會問到,如果有程式在 WndProc 當中再寫一個無窮迴圈,那麼 Windows 3.1 的系統會發生甚麼事呢?這個問題的答案很簡單,那就是整個作業系統都會當機,因為,在『協同式多工』的架構底下,只要有一個程式不願意交回控制權,其他程式 (包含作業系統) 也都無可奈何。這種程式設計的方式仰賴所有程式共同合作,準時交回控制權,因此,才被稱為『協同式多工』,因為,所有程式都必須同心協力,系統才不會當機。
page revision: 0, last edited: 24 Mar 2010 05:20
Post preview:
Close preview