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 的系統會發生甚麼事呢?這個問題的答案很簡單,那就是整個作業系統都會當機,因為,在『協同式多工』的架構底下,只要有一個程式不願意交回控制權,其他程式 (包含作業系統) 也都無可奈何。這種程式設計的方式仰賴所有程式共同合作,準時交回控制權,因此,才被稱為『協同式多工』,因為,所有程式都必須同心協力,系統才不會當機。

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License