void pop()
{
std::lock_guard<std::mutex>lock(mtx);
if (base != NULL)
{
StackNode* q = base;
base = q->next;
&(q->data)->~T();
Freenode(q);
cursize -= 1;
}
}
&(q->data)->~T();//类似于定位new
new的三种构建方式:
Testp=new Test(10)//申请空间 构建对象 返回对象地址 (在多核CPU上二三步骤可能错位)
Tests=(Test*)::operator new(sizeof(Test));//和malloc的最大区别就是,malloc在空间不足时,会返回一个NULL,而operator new会抛出一个异常
new(s)Test(10)//定位new,不管是malloc申请的,还是operator new来的,定位new都可在申请的空间中构建对象
在释放节点空间之前,必须将节点里边的对象析构掉(楼房拆迁前,必须把人员全都撤离)
改为原子操作:
完整代码:
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include <semaphore>
using namespace std;
template<class T>
class Stack
{
private:
struct StackNode
{
T data;
StackNode* next;
};
StackNode* Buynode()
{
StackNode* s = (StackNode*)malloc(sizeof(StackNode));
if (NULL == s)exit(1);
memset(s, 0, sizeof(StackNode));
return s;
}
void Freenode(StackNode* s)
{
free(s);
}
private:
StackNode* base;
size_t cursize;
mutable std::atomic<StackNode*>pHead;
Stack(const Stack&) = delete;
Stack& operator=(const Stack&) = delete;
public:
Stack() :base(NULL), cursize(0) {}
~Stack() {}
void Push(const T& val)
{
StackNode* newnode = Buynode();
new(&(newnode->data))T(val);
//newnode->next = pHead;
newnode->next = pHead.load();
while (!pHead.compare_exchange_weak(newnode->next, newnode));
//pHead = newnode;
}
};
void thread_funa(Stack<int>& s)
{
for (int i = 0; i < 10; i += 2)
{
cout << i << endl;
s.Push(i);
}
}
void thread_funb(Stack<int>& s)
{
for (int i = 1; i < 10; i += 2)
{
cout << i << endl;
s.Push(i);
}
}
int main()
{
Stack<int>ist;
thread tha(thread_funa, std::ref(ist));
thread thb(thread_funb, std::ref(ist));
tha.join();
thb.join();
return 0;
}