赞
踩
当CPU访问的页面不在内存时,便会产生缺页中断,请求操作系统将所缺页从硬盘中调入到内存里。
和一般中断的区别:
是指令执行期间产生和处理中断信号
一般中断程序计数器返回的时候会执行下一条指令,而缺页中断需要重新执行该条指令。
流程:
选择在内存中驻留时间最长的页面,垃圾
选择最长时间没有被访问的页面进行置换。看上去不错,实际不怎么用。
struct DLinkedNode { int key, value; DLinkedNode* prev; DLinkedNode* next; DLinkedNode(): key(0), value(0), prev(nullptr), next(nullptr) {} DLinkedNode(int _key, int _value): key(_key), value(_value), prev(nullptr), next(nullptr) {} }; class LRUCache { private: unordered_map<int, DLinkedNode*> cache; DLinkedNode* head; DLinkedNode* tail; int size; int capacity; public: LRUCache(int _capacity): capacity(_capacity), size(0) { // 使用伪头部和伪尾部节点 head = new DLinkedNode(); tail = new DLinkedNode(); head->next = tail; tail->prev = head; } int get(int key) { if (!cache.count(key)) { return -1; } // 如果 key 存在,先通过哈希表定位,再移到头部 DLinkedNode* node = cache[key]; moveToHead(node); return node->value; } void put(int key, int value) { if (!cache.count(key)) { // 如果 key 不存在,创建一个新的节点 DLinkedNode* node = new DLinkedNode(key, value); // 添加进哈希表 cache[key] = node; // 添加至双向链表的头部 addToHead(node); ++size; if (size > capacity) { // 如果超出容量,删除双向链表的尾部节点 DLinkedNode* removed = removeTail(); // 删除哈希表中对应的项 cache.erase(removed->key); // 防止内存泄漏 delete removed; --size; } } else { // 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部 DLinkedNode* node = cache[key]; node->value = value; moveToHead(node); } } void addToHead(DLinkedNode* node) { node->prev = head; node->next = head->next; head->next->prev = node; head->next = node; } void removeNode(DLinkedNode* node) { node->prev->next = node->next; node->next->prev = node->prev; } void moveToHead(DLinkedNode* node) { removeNode(node); addToHead(node); } DLinkedNode* removeTail() { DLinkedNode* node = tail->prev; removeNode(node); return node; } };
class LRUCache { public: //定义双链表 struct node { int key,value; node *pre,*next; node(int k,int v):key(k),value(v),pre(NULL),next(NULL) {} }*dummy_head,*dummy_tail; unordered_map<int,node*> mp; int n; LRUCache(int capacity) { n=capacity; dummy_head=new node(-1,-1),dummy_tail= new node(-1,-1); dummy_head->next=dummy_tail; dummy_tail->pre=dummy_head; } //删除p节点 void remove_p(node *p) { p->pre->next=p->next; p->next->pre=p->pre; } //插入节点到dummy_head后 void insert_to_first(node* p) { p->next=dummy_head->next; p->pre=dummy_head; dummy_head->next->pre=p; dummy_head->next=p; } int get(int key) { if(mp.count(key)==0) return -1; //有,则返回其值,把该节点从双向链表中移动到第一个,以此表示刚被使用过 node* temp=mp[key]; remove_p(temp); insert_to_first(temp); return temp->value; } void put(int key, int value) { //考虑几个问题,容量满没满,有没有。如果有,不涉及容量问题,如果没有才涉及容量问题 if(mp.count(key))//命中,修改其值,以及在双向链表位置 { node* temp=mp[key]; temp->value=value; remove_p(temp); insert_to_first(temp); } else { //容量已满,将最后一个节点从双向链表删除,与此同时删除哈希表中该值 if(mp.size()==n) { node* need_remove=dummy_tail->pre; cout<<"delete node"<<need_remove->key<<endl; remove_p(need_remove); mp.erase(need_remove->key); } node* p=new node(key,value); //将该节点插入到hash表以及双向链表 mp[key]=p; insert_to_first(p); } } }; /** * Your LRUCache object will be instantiated and called as such: * LRUCache* obj = new LRUCache(capacity); * int param_1 = obj->get(key); * obj->put(key,value); */
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。