Skip to content
APTXASZC edited this page Jun 21, 2023 · 10 revisions

##2023

2023-3-15

// 1. sprintf(char* tar,const char* src);
// 将src的内容复制到tar中
char buf[256];
sprintf(buf,"hello world %d",618);
fputs(buf);

2023-5-26 弱回调 $核心思路:bind对象成员方法以及该成员的weak_ptr,使用该方法时上升weak_ptr来判断对象是否销毁

class stock		// 股票类,里面有股票的名字和价值
{
public:
	stock(const string& s):name(s),value(5) {}
	string name;
	double value;
};

class stockFactory :public enable_shared_from_this<stockFactory>	// 股票工厂类,继承了enable_shared_from_this来让this指针是shared,这样使用bind时能让this的引用计数+1进而使得factory不会在stock之前销毁(因为stock销毁时要保证在factory的hashtable中删除以避免内存泄漏,因此stock析构时不可避免的要调用factory中的方法)
{
public:
	shared_ptr<stock> get(string const key)
	{
		shared_ptr<stock> p;
		lock_guard<mutex> lk(mut);
		weak_ptr<stock>& wk = stocks[key];
		p = wk.lock();
		if (!p)
		{		// 弱回调技术 : 区别于前述的factory延寿方法,有时需要 对象还活着时,调用其成员函数,否则忽视 这样的语义,也就是不延长对象的生命并且要让程序完好的执行
			p.reset(new stock(key), bind(&stockFactory::weakDeleteCallback, weak_ptr<stockFactory>(shared_from_this()), placeholders::_1)); // 这里用weak_ptr来强转shared的this指针以保证bind时this指针生命周期不变,并且在之后通过上升来判断factory是否销毁以分别操作
			wk = p;
			// bind将函数托管给functional,其生命周期比较长
		}
		return p;
	}

private:
	static void weakDeleteCallback(const weak_ptr<stockFactory>& wkf,stock* st)
	{
		shared_ptr<stockFactory> t(wkf.lock());
		if (t)
		{
			t->removeStock(st);
		}
		delete st;
	}
	void removeStock(stock* s)
	{
		if (s)
		{
			lock_guard<mutex> lk(mut);
			stocks.erase(s->name);
		}
	}
	
	mutable mutex mut;
	unordered_map<string, weak_ptr<stock>> stocks;
};



class beCall
{
public:

	void hlwd(const weak_ptr<beCall>& s)
	{
		shared_ptr<beCall> t = s.lock();
		if (t)
		{
			cout << "beCall还没被销毁" << endl;
		}
		else
		{
			cout << "beCall已经被销毁" << endl;
		}
		return;
	}
};
int main() {

	shared_ptr<beCall> p(new beCall);

	auto f = bind(&(beCall::hlwd),cref(p), weak_ptr<beCall>(p));
	
	p.reset();

	f();

	return 0;


}

这里mutable是为了让const对象也能调用内部互斥

2023-5-30

$spurious \ wake$ $解释:若prepare线程notify后,有别的线程在process线程醒来前lock,该线程处理完后process线程才被唤醒执行,则称为spurious wake$

$条件变量$

condition_variable.notify_one()  // prepare线程完成prepare后可以调用该方法通知process线程
condition_variable.wait(lock,func)  // func成立则继续向下执行,否则unlock and sleep,sleep时被notify则醒来lock再check func

$strtod()和一些手法$

double strtod(const char* s,char** str_end);
// 将s转化为double类型并返回
// s指向字符串的首地址,执行完后*str_end指向转换完的字符最后一位的下一位,如果里面没有数字(或者称为可转化对象),则end不会移动,在s=end赋值后执行strtod,判断s==end就可以跳出了

printf("'%.*s' -> ", (int)(end-p), p);  // 打印s并且保留字符'.'后面end-p位

$2023-6-21$

template<typename T>
class safe_queue {
private:
	struct node {	// 节点的核心 : 数据以及next指针
		shared_ptr<T> data;
		unique_ptr<node> next;
	};
	unique_ptr<node> head;
	node* tail;
	mutex head_mut;
	mutex tail_mut;
	condition_variable cv;

public:
	safe_queue():head(new node),tail(head.get()){}	// 初始化一下,保证一开始整个queue是空的
	safe_queue(const safe_queue&) = delete;
	safe_queue& operator=(const safe_queue&) = delete;


	node* get_tail()	// 即使是拿tail,也要保证线程安全
	{
		lock_guard<mutex> lk(tail_mut);
		return tail;
	}
	unique_lock<mutex> wait_for_data()	// 这里等待队列非空
	{
		unique_lock<mutex> lk(head_mut);
		cv.wait(lk, [] {return head.get() != get_tail(); });
		return move(lk);	// 将锁交给调用者
	}
	unique_ptr<node> pop_head()	// 辅助函数弹首操作
	{
		unique_ptr<node> old_head = move(head);
		head = move(head->next);
		return old_head;
	}
	unique_ptr<node> wait_pop_head()	
	{
		unique_lock<mutex> lk(wait_for_data());
		return pop_head();
	}
	unique_ptr<node> wait_pop_head(T& val)
	{
		unique_lock<mutex> lk(wait_for_data());
		val = move(*head->data);
		return pop_head();	
	}
	void push(T val)	// 推入数据,同时通知wait_for_data
	{
		shared_ptr<T> dt = make_shared<T>(move(val));
		unique_ptr<node> p(new node);
		{
			lock_guard<mutex> lk(tail_mut);
			const node* new_tail = p.get();
			tail->data = dt;
			tail->next = move(p);
			tail = new_tail;
		}
		cv.notify_one();
	}
	shared_ptr<T> wait_and_pop()
	{
		const unique_ptr<node> old_head = wait_pop_head();
		return old_head->data;
	}
	void wait_and_pop(T& val)
	{
		const unique_ptr<node> old_head = wait_pop_head();
		val = *(old_head->data);
	}
};
Clone this wiki locally