内存池
1.避免内存的分配开销,和内存碎片
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| #include "iostream" #include <cstddef> #include <string>
template<typename T,size_t PoolSize> class ObjectPool { struct Slot { alignas(alignof(T)) char data[sizeof(T)]; Slot* next; };
Slot* freeList; Slot pool[PoolSize];
public: ObjectPool() { freeList = &pool[0]; for (size_t i = 0; i < PoolSize-1; ++i) { pool[i].next = &pool[i + 1]; } pool[PoolSize - 1].next = nullptr; }
T* Allocate() { if (!freeList) { return nullptr; } Slot* slot = freeList; freeList = slot->next;
T* obj = new (slot->data) T(); return obj; }
void Deallocate(T* obj) { if (obj) { obj->~T(); Slot* slot = reinterpret_cast<Slot*>(obj); std::cout<< slot->data << std::endl; slot->next = freeList; freeList = slot; } }
};
class MyClass{ std::string name; int value; public: MyClass():name("default"),value(0) { std::cout<<"MyClass constructed"<<std::endl; } ~MyClass(){ std::cout<<"MyClass destoryed"<<std::endl; } void setValue(int v){value = v;} void setName(const std::string& n){ name = n; }
void print() const{ std::cout<<"Name: " <<name<<",Value "<<value<<std::endl; } };
int main() { ObjectPool<MyClass, 10> pool;
MyClass* obj1 = pool.Allocate(); MyClass* obj2 = pool.Allocate(); MyClass* obj3 = pool.Allocate();
if(obj1){ obj1->setName ("object1"); obj1->setValue(100); obj1->print(); }
if(obj2){ obj2->setName ("object2"); obj2->setValue(200); obj2->print(); }
if(obj3){ obj3->setName ("object3"); obj3->setValue(200); obj3->print(); }
pool.Deallocate(obj2);
MyClass* obj4 = pool.Allocate(); obj4->print(); return 0; }
|
Mutex 线程锁
避免C++多线程对同一数据写入和读取,产生的错误
1. 锁 std::mutex
1.创建std::mutex mtx 对象 用mtx.lock()上锁 mtx.unlock() 解锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include <iostream> #include <thread> #include <vector> #include <mutex> #include <chrono> #include <stdexcept>
int counter = 0; std::mutex mtx;
void increase(int time) { for (int i = 0; i < time; i++) { mtx.lock(); std::this_thread::sleep_for(std::chrono::milliseconds(1)); counter++; mtx.unlock(); } }
int main(int argc, char** argv) { std::thread t1(increase, 10000); std::thread t2(increase, 10000); t1.join(); t2.join(); std::cout << "counter:" << counter << std::endl; return 0; }
|
使用std::mutex 有个问题.如果一个线程里中有有异常,返回的异常的时候没有 解锁,导致其他线程的锁死。所以引入:std::lock_guard
2. std::lock_guard
声明lock_guard 后自动进行lock() 上锁,离开作用域后会自动unlock() 解锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include <iostream> #include <thread> #include <vector> #include <mutex> #include <chrono> #include <stdexcept>
int counter = 0; std::mutex mtx;
void increase_proxy(int time, int id) { for (int i = 0; i < time; i++) { std::lock_guard<std::mutex> lk(mtx); if (id == 1) { throw std::runtime_error("throw excption...."); } std::this_thread::sleep_for(std::chrono::milliseconds(1)); counter++; } }
void increase(int time, int id) { try { increase_proxy(time, id); } catch (const std::exception& e){ std::cout << "id:" << id << ", " << e.what() << std::endl; } }
int main(int argc, char** argv) { std::thread t1(increase, 10000, 1); std::thread t2(increase, 10000, 2); t1.join(); t2.join(); std::cout << "counter:" << counter << std::endl; return 0; }
|
如果想在线程里执行多次的lock() 和unlock() 就需要引入std::unique_lock,离开作用域自动解锁,支持条件判断,就需要使用std::unique_lock
3. std::unique_lock
1.普通用法
1 2 3 4 5 6 7 8 9 10 11 12 13
| std::mutex mtx;
void func() { std::unique_lock<std::mutex> lock(mtx, std::defer_lock); lock.lock(); lock.unlcok() lock.lock() }
|
2.延迟加锁
1 2 3 4 5 6 7 8 9
| std::mutex mtx;
void func() { std::unique_lock<std::mutex> lock(mtx, std::defer_lock); lock.lock(); }
|
3.加锁判断
1 2 3 4 5 6 7 8 9 10
| std::mutex mtx; std::condition_variable cv; bool ready = false;
void wait_thread() { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, []{ return ready; }); }
|
4. std::shared_lock() 共享锁多个线程共享 用在读取数据