BUAA OO 電梯排程

2022-08-05 11:33:14 字數 2025 閱讀 7325

設計一個系統,使其可以根據乘客的當前樓層和目的樓層,為乘客分配電梯資源並運送其至目的樓層。

根據需求,可以將整個系統分成三個部分:

顯然,這三個部分是有次序關係的:乘客輸入,處理輸入,將請求放入排程佇列,排程器從排程佇列中取出請求,根據各電梯狀態將請求分配給合適的電梯。

上述的過程可以看成是三組 producer-consumer 組:

輸入處理

阻塞式獲取輸入,直到檢測到 eof 或者輸入流關閉。處理後的請求儲存在 personrequest 類中。當獲取到合法請求,將請求存入排程佇列,喚醒排程器。

排程器從排程佇列中取出請求,根據電梯狀態來決定請求被分配至的電梯,對於需要換乘的請求,將後續請求也分配至同一電梯,待前置請求完成,重新對後續請求進行排程。這裡的電梯狀態包括但不止於電梯能夠停靠的樓層、電梯當前執行狀態、電梯當前的任務序列、電梯歷史執行狀態。前兩者對於排程起著決定性的作用,而後兩者主要是使得各電梯負載均衡。

電梯從任務序列中取出任務,前往指定樓層執行任務。若完成了某個需換乘請求的前置請求,將後續請求提交給排程器,使其被重新排程。

elevator

├── direction

├── dispatcher

├── dividetask

├── elevator

├── elevatorrequest

├── inputhandler

├── main

├── requestqueue

├── task

└── timer

inputhandler

顧名思義,用於處理乘客輸入的類。域中包含有一個排程器(dispatcher 類例項)。

當獲取到合法輸入時,喚醒(notify)排程器,否則堵塞。

當輸入為 eof 或者流被關閉時,將排程器的狀態設定為停止狀態(false),並喚醒(notify)排程器。

dispatcher

排程器類。域中包含有

當排程佇列為空,進入等待狀態(wait)。

被喚醒後,從排程佇列中依次取出所有請求並進行分配。全部取出後,若狀態為執行狀態(true),重新進入等待狀態(wait);否則,將所有電梯的狀態設定為停滯狀態(false),並依次喚醒,最後結束排程器執行緒,但是保留排程器例項。

elevator

電梯類。域中包含有

電梯執行總體採用 look 演算法:在不轉向的前提下先執行完畢一個方向的任務,然後切換為另一個方向的任務序列,繼續執行。執行過程中的等待過程都通過 timer 類來實現。

task

任務類。單純的資料聚合。域中包含有

elevatorrequest

電梯任務類。域中包含有

當電梯接收到請求,會將請求存入 elevatorrequest 中。首先進行方向的判斷,並將其拆分為兩個任務:一個 in,一個 out。然後判斷加入主任務序列或是加入副任務序列:若與電梯的任務方向相反,或者可以捎帶,則加入主任務序列,否則加入副任務序列。

當主任務序列為空,電梯轉向時,進行 fresh 操作,將主任務序列與副任務序列互換。

dividerequest

待排程請求類。單純的資料聚合。域中包含有

如下,與上述的設計描述大致相同。

使用 complexity mertics 生成。

總體而言,複雜度尚可,複雜度較高的幾個 method 都是與設計緊密相關的,沒有修改或者拆分的必要。

在第二次電梯作業中,由於電梯的上下極限從 1-15 變為-3-20,而我在第一次作業中空任務的標誌 magic number 設定為了 0 忘記修改,導致第二次作業出現了問題。由此可以看出測試的重要性,因而第三次作業我專門寫了一個評測機放在伺服器上進行長時間測試。

在多執行緒程式設計中,要特別關注暴露在多個執行緒之外的***,嚴格控制進入臨界區的執行緒數量。

2021 BUAA OO第一單元總結

oo第一單元總結 第一次作業 一 題目要求 簡單多項式求導,僅支援常數與冪函式的乘積作為項,保證輸入無格式錯誤。 二 作業實現及分析 由於第一次作業要求實現的功能並不複雜,且我當時對於物件導向的理解並不夠深入,所以我當時只是根據自己的想法構建了4個類來解決這個問題 類圖如下 關鍵類分析如下 stri...

BUAA OO 第一次部落格作業

第一次作業 第一次進行物件導向的程式設計,不論是針對資料設計類還是對方法進行合適的歸於不同類中,都不是很熟悉。所寫出來的程式還是程序導向 有函式的類 雖然現在很大程度上感覺起來也是這樣 。索性作業難度並不算高,完成的也算馬馬虎虎。公測都通過了,但是互測的時候被發現了一處筆誤,少寫了一個0,導致6位的測試...