sprmrkt.c

来自「一本已经绝版的好书」· C语言 代码 · 共 555 行 · 第 1/2 页

C
555
字号
            GetDlgItem(hwnd, IDC_TIMEATCHECKOUT));


         // Clear out everything in the list box.
         ListBox_ResetContent(
            GetDlgItem(hwnd, IDC_SHOPPEREVENTS));

         // Disable the Open For Business button
         // while simulation is in progress.

         EnableWindow(hwndCtl, FALSE);

         if (NULL == GetFocus()) {
            SetFocus(GetDlgItem(hwnd, IDC_MAXOCCUPANCY));
         }


         // The system overhead will cause the results
         // of the simulation to be skewed. To help
         // minimize this effect, we boost the priority class
         // of this process.
         SetPriorityClass(GetCurrentProcess(),
            HIGH_PRIORITY_CLASS);

         // Create the thread representing the supermarket.
         hThread = chBEGINTHREADEX(
            NULL,              // Security attributes
            0,                 // Stack
            ThreadSuperMarket, // Thread function
            (LPVOID) hwnd,     // Thread function parameter
            0,                 // Flags
            &dwThreadId);      // Thread ID    
            
         // Since we are not interested in manipulating the
         // thread object from this function, we can close
         // our handle to it.
         CloseHandle(hThread);
         break;

      case IDCANCEL:
         EndDialog(hwnd, id);
         break;
   }
}


//////////////////////////////////////////////////////////////


BOOL CALLBACK Dlg_Proc (HWND hwnd, UINT uMsg,
   WPARAM wParam, LPARAM lParam) {

   switch (uMsg) {
      chHANDLE_DLGMSG(hwnd, WM_INITDIALOG,  Dlg_OnInitDialog);
      chHANDLE_DLGMSG(hwnd, WM_COMMAND,  Dlg_OnCommand);
      chHANDLE_DLGMSG(hwnd, WM_HSCROLL,  Dlg_OnHScroll);

      case WM_USER:
         // This message is sent by the SuperMarketThread 
         // function to notify us that the simulation 
         // has completed.

         // Return the priority class of the simulation
         // back to normal.
         SetPriorityClass(GetCurrentProcess(),
            NORMAL_PRIORITY_CLASS);

         // Enable the Open For Business button so that
         // the user can run the simulation again with
         // new parameters.
         EnableWindow(GetDlgItem(hwnd, IDOK), TRUE);
         break;
   }
   return(FALSE);
}


//////////////////////////////////////////////////////////////


int WINAPI _tWinMain (HINSTANCE hinstExe,
   HINSTANCE hinstPrev, LPTSTR pszCmdLine, int nCmdShow) {

   chWARNIFUNICODEUNDERWIN95();
   DialogBox(hinstExe, MAKEINTRESOURCE(IDD_SPRMRKT),
      NULL, Dlg_Proc);

   return(0);
}


//////////////////////////////////////////////////////////////


DWORD WINAPI ThreadSuperMarket (LPVOID lpvParam) {
   DWORD dwCloseTime;
   HANDLE hThread;
   DWORD dwThreadId;
   int nShopperNum = 0, nMaxOccupancy;

   g_hSemEntrance = CreateSemaphore(
      NULL,                // Security attributes
      0,                   // Initial lock count
      g_nMaxOccupancy,     // Maximum people allowed in store
      NULL);               // Do not name the semaphore.

   g_hMtxDeliCntr = CreateMutex(
      NULL,                // Security attributes
      FALSE,               // Initially no one is at the deli.
      NULL);               // Do not name the mutex.

   g_hSemCheckout = CreateSemaphore(
      NULL,                // Security attributes
      g_nCheckoutCounters, // All counters are free.
      g_nCheckoutCounters, // The number of counters at the store
      NULL);               // No name for the semaphore


   // Open the store to the shoppers.
   AddStr(__TEXT("---> Opening the supermarket to shoppers."));
   ReleaseSemaphore(g_hSemEntrance, g_nMaxOccupancy, NULL);

   // Get the time at which the store should
   // stop creating shoppers.
   dwCloseTime = GetTickCount() + g_nTimeOpen;

   // Continue loop until the store closes.
   while (GetTickCount() < dwCloseTime) {

      // Create the thread representing a shopper.
      hThread = chBEGINTHREADEX(
         NULL,                   // Security attributes
         0,                      // Stack
         ThreadShopper,          // Thread function
         (LPVOID) ++nShopperNum, // Shopper number as lpvParam
         0,                      // Flags
         &dwThreadId);           // Thread ID

      // Since we are not interested in manipulating the
      // thread object from this function, we can close
      // our handle to it.
      CloseHandle(hThread);

      // Wait until another shopper comes to the supermarket.
      Sleep(Random(g_nMaxDelayBetweenShopperCreation));
   }

   // The supermarket wants to close;
   // wait for all of the shoppers to leave.
   AddStr(__TEXT("---> Waiting for shoppers to check out ")
      __TEXT("so store can close."));

   nMaxOccupancy = 1;
   for (; nMaxOccupancy <= g_nMaxOccupancy; nMaxOccupancy++) {
      WaitForSingleObject(g_hSemEntrance, INFINITE);
      AddStr(__TEXT("---> %d shoppers NOT in store."),
      nMaxOccupancy);
   }

   AddStr(__TEXT("---> Store closed--end of simulation."));

   // Everybody has left the market--end of simulation.
   CloseHandle(g_hSemCheckout);
   CloseHandle(g_hMtxDeliCntr);
   CloseHandle(g_hSemEntrance);

   // Notify the GUI thread that the simulation has completed.
   // The window handle of the GUI thread's dialog box was
   // passed in the lpvParam parameter to this thread when
   // it was created.
   SendMessage((HWND) lpvParam, WM_USER, 0, 0);

   return(0);
}


//////////////////////////////////////////////////////////////


DWORD WINAPI ThreadShopper (LPVOID lpvParam) {
   int nShopperNum = (int) lpvParam;
   DWORD dwResult;
   int nDuration;

   // Seed the random number generator for this thread
   // or every shopper thread will use the same seed and
   // generate the same set of random numbers.
   srand(GetTickCount() * nShopperNum);

   // Wait till the shopper can enter the supermarket.
   nDuration = Random(g_nMaxWaitToGetInMarket);
   AddStr(__TEXT("%04lu: Waiting to get in store (%lu)."),
      nShopperNum, nDuration);

   dwResult = WaitForSingleObject(g_hSemEntrance, nDuration);
   if (dwResult == WAIT_TIMEOUT) {
      // The shopper got tired of
      // waiting to be let in and left.
      AddStr(__TEXT("%04lu: Tired of waiting; went home."),
      nShopperNum);
      return(0);
   }


   // Shopper entered the supermarket.  Time to go shopping.
   nDuration = Random(g_nMaxTimeShopping);
   AddStr(__TEXT("%04lu: In supermarket, shopping for %lu."),
      nShopperNum, nDuration);
   Sleep(nDuration);


   // Done with initial shopping. Shopper has a one-in-three
   // chance of going to the deli counter.
   if (Random(2) == 0) {

      // Shopper going to deli counter.
      nDuration = Random(g_nMaxWaitForDeliCntr);
      AddStr(
         __TEXT("%04lu: Waiting for service at ")
         __TEXT("Deli Counter (%lu)."),
         nShopperNum, nDuration);
      dwResult =
         WaitForSingleObject(g_hMtxDeliCntr, nDuration);

      if (dwResult == 0) {
         // Got attention at deli; order stuff.
         nDuration = Random(g_nMaxTimeSpentAtDeli);

         AddStr(__TEXT("%04lu: Being served at Deli (%lu)."),
            nShopperNum, nDuration);
         Sleep(nDuration);

         // Leave the deli counter.
         ReleaseMutex(g_hMtxDeliCntr);

      } else {
         // Tired of waiting at deli counter,
         // leave and continue shopping.
         AddStr(__TEXT("%04lu: Tired of waiting at Deli."),
            nShopperNum);
      }

   } else {
      AddStr(__TEXT("%04lu: Not going to the Deli counter."),
         nShopperNum);
   }


   // Waiting for a checkout counter.
   AddStr(
      __TEXT("%04lu: Waiting for an empty checkout counter."),
      nShopperNum);
   WaitForSingleObject(g_hSemCheckout, INFINITE);

   // Checking out.
   nDuration = Random(g_nMaxTimeAtCheckout);
   AddStr(__TEXT("%04lu: Checking out (%lu)."),
      nShopperNum, nDuration);
   Sleep(nDuration);

   // Leaving the checkout counter.
   AddStr(__TEXT("%04lu: Leaving checkout counter."),
      nShopperNum);
   ReleaseSemaphore(g_hSemCheckout, 1, NULL);

   // Leaving the store.
   AddStr(__TEXT("%04lu: Left the supermarket."),
      nShopperNum);
   ReleaseSemaphore(g_hSemEntrance, 1, NULL);

   // Shopper shopped till he/she dropped.  Shopper dead.
   return(0);
}


//////////////////////// End Of File /////////////////////////

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?