#ifndef RESOURCE_MANAGER_H #define RESOURCE_MANAGER_H #include "graph_map.h" #include #include #include #include #include #include #include /** * @brief 资源请求状态 */ enum class ResourceRequestStatus { GRANTED, // 已授予 PENDING, // 等待中 TIMEOUT, // 超时 CANCELLED // 已取消 }; /** * @brief 资源请求 */ struct ResourceRequest { int id; AGV* agv; Path* path; uint64_t timestamp; ResourceRequestStatus status; std::condition_variable* condition; // 用于通知 ResourceRequest(int id_, AGV* agv_, Path* path_) : id(id_), agv(agv_), path(path_), timestamp(getCurrentTimestamp()), status(ResourceRequestStatus::PENDING), condition(nullptr) {} bool operator<(const ResourceRequest& other) const { // 可以根据优先级或其他规则排序 return timestamp < other.timestamp; // FIFO } private: static uint64_t getCurrentTimestamp() { return std::chrono::duration_cast( std::chrono::steady_clock::now().time_since_epoch()).count(); } }; /** * @brief 资源管理器 * 负责管理路径和节点的占用 */ class ResourceManager { private: // 资源占用状态 std::unordered_map path_occupancy_; std::unordered_map point_occupancy_; // 等待队列(路径和节点) std::unordered_map> path_wait_queue_; std::unordered_map> point_wait_queue_; // 互斥锁 mutable std::mutex resource_mutex_; // 请求ID生成器 std::atomic next_request_id_{1}; // 统计信息 std::atomic total_requests_{0}; std::atomic granted_requests_{0}; std::atomic wait_count_{0}; public: ResourceManager() = default; ~ResourceManager() = default; /** * @brief 请求占用路径 * @param agv 请求的AGV * @param path 要占用的路径 * @param timeout_ms 超时时间(毫秒),0表示无限等待 * @return 请求状态 */ ResourceRequestStatus requestPath(AGV* agv, Path* path, int timeout_ms = 0); /** * @brief 释放路径资源 * @param agv 释放的AGV * @param path 释放的路径 */ void releasePath(AGV* agv, Path* path); /** * @brief 检查路径是否可用 * @param path 要检查的路径 * @param requester 请求的AGV(如果是自己占用也算可用) * @return 是否可用 */ bool isPathAvailable(Path* path, AGV* requester = nullptr); /** * @brief 请求占用节点 * @param agv 请求的AGV * @param point 要占用的节点 * @param timeout_ms 超时时间 * @return 请求状态 */ ResourceRequestStatus requestPoint(AGV* agv, Point* point, int timeout_ms = 0); /** * @brief 释放节点资源 * @param agv 释放的AGV * @param point 释放的节点 */ void releasePoint(AGV* agv, Point* point); /** * @brief 检查节点是否可用 * @param point 要检查的节点 * @param requester 请求的AGV * @return 是否可用 */ bool isPointAvailable(Point* point, AGV* requester = nullptr); /** * @brief 获取占用路径的AGV * @param path 路径 * @return 占用的AGV,如果没有则返回nullptr */ AGV* getPathOccupant(Path* path) const; /** * @brief 获取占用节点的AGV * @param point 节点 * @return 占用的AGV,如果没有则返回nullptr */ AGV* getPointOccupant(Point* point) const; /** * @brief 强制释放AGV占用的所有资源(用于错误处理) * @param agv 要释放资源的AGV */ void releaseAllResources(AGV* agv); /** * @brief 获取统计信息 */ void getStatistics(uint64_t& total_requests, uint64_t& granted_requests, uint64_t& wait_count) const; /** * @brief 打印资源占用状态 */ void printResourceStatus() const; /** * @brief 检测死锁 * @return 发现的死锁数量 */ int detectDeadlocks(); private: /** * @brief 处理等待队列 * 当资源释放时,检查等待队列并分配给下一个请求 */ void processWaitQueue(Path* path); void processWaitQueue(Point* point); /** * @brief 取消请求 */ void cancelRequest(ResourceRequest* request); /** * @brief 检查循环等待(死锁检测) */ bool hasCircularWait(AGV* agv, std::unordered_set& visited, std::unordered_set& path_set); /** * @brief 记录统计信息 */ void recordRequest(bool granted); }; /** * @brief 资源自动管理器 * 使用RAII模式自动管理资源 */ class ScopedPathResource { private: ResourceManager* manager_; AGV* agv_; Path* path_; bool acquired_; public: ScopedPathResource(ResourceManager* manager, AGV* agv, Path* path) : manager_(manager), agv_(agv), path_(path), acquired_(false) { if (manager_ && agv_ && path_) { auto status = manager_->requestPath(agv_, path_); acquired_ = (status == ResourceRequestStatus::GRANTED); } } ~ScopedPathResource() { if (acquired_ && manager_ && agv_ && path_) { manager_->releasePath(agv_, path_); } } bool isAcquired() const { return acquired_; } // 禁止拷贝 ScopedPathResource(const ScopedPathResource&) = delete; ScopedPathResource& operator=(const ScopedPathResource&) = delete; }; /** * @brief 节点资源自动管理器 */ class ScopedPointResource { private: ResourceManager* manager_; AGV* agv_; Point* point_; bool acquired_; public: ScopedPointResource(ResourceManager* manager, AGV* agv, Point* point) : manager_(manager), agv_(agv), point_(point), acquired_(false) { if (manager_ && agv_ && point_) { auto status = manager_->requestPoint(agv_, point_); acquired_ = (status == ResourceRequestStatus::GRANTED); } } ~ScopedPointResource() { if (acquired_ && manager_ && agv_ && point_) { manager_->releasePoint(agv_, point_); } } bool isAcquired() const { return acquired_; } // 禁止拷贝 ScopedPointResource(const ScopedPointResource&) = delete; ScopedPointResource& operator=(const ScopedPointResource&) = delete; }; #endif // RESOURCE_MANAGER_H