当前位置: 首页 > news >正文

买源码做网站wordpress 系列教程

买源码做网站,wordpress 系列教程,白山网站建设,公司网站建设外包本文介绍C 并发中使用的其他类型的锁#xff0c;包括unique_lock#xff0c;shared_lock, 以及recursive_lock等。shared_lock和unique_lock比较常用#xff0c;而recursive_lock用的不多#xff0c;或尽可能规避用这种锁。 unique_lock unique_lock和lock_guard基本用法…本文介绍C 并发中使用的其他类型的锁包括unique_lockshared_lock, 以及recursive_lock等。shared_lock和unique_lock比较常用而recursive_lock用的不多或尽可能规避用这种锁。 unique_lock unique_lock和lock_guard基本用法相同构造时默认加锁析构时默认解锁但unique_lock有个好处就是可以手动解锁。这一点尤为重要方便我们控制锁住区域的粒度(加锁的范围大小),也能支持和条件变量配套使用至于条件变量我们之后再介绍本文主要介绍锁的相关操作。 #includeiostream #includemutex #includestack #includememory #includethread using std::cout; using std::endl;//unique_lock 开始 std::mutex mtx; int shared_data 0; void use_unique() {//lock可自动解锁也可手动解锁std::unique_lockstd::mutex lock(mtx);std::cout lock success std::endl;shared_data;lock.unlock(); }// 我们可以通过unique_lock的owns_lock判断是否持有锁 //可判断是否占有锁 void owns_lock() {//lock可自动解锁也可手动解锁std::unique_lockstd::mutex lock(mtx);shared_data;if (lock.owns_lock()) {std::cout owns lock std::endl; // True}else {std::cout doesnt own lock std::endl;}lock.unlock();if (lock.owns_lock()) {std::cout owns lock std::endl;}else {std::cout doesnt own lock std::endl; // True} }//unique_lock可以延迟加锁 //可以延迟加锁 void defer_lock() {//延迟加锁std::unique_lockstd::mutex lock(mtx, std::defer_lock);if (lock.owns_lock()) {std::cout owns lock std::endl; // False}if (lock.owns_lock()) {std::cout owns lock std::endl;}else {std::cout doesnt own lock std::endl; // True}//可以加锁lock.lock();//可以自动析构解锁也可以手动解锁lock.unlock(); }//unique_lock 结束 int main() {//use_unique();//owns_lock();defer_lock();return 0; }整合运用 #includeiostream #includemutex #includestack #includememory #includethread using std::cout; using std::endl;//unique_lock 开始 std::mutex mtx; int shared_data 0; void use_unique() {//lock可自动解锁也可手动解锁std::unique_lockstd::mutex lock(mtx);std::cout lock success std::endl;shared_data;lock.unlock(); }// 我们可以通过unique_lock的owns_lock判断是否持有锁 //可判断是否占有锁 void owns_lock() {//lock可自动解锁也可手动解锁std::unique_lockstd::mutex lock(mtx);shared_data;if (lock.owns_lock()) {std::cout owns lock std::endl; // True}else {std::cout doesnt own lock std::endl;}lock.unlock();if (lock.owns_lock()) {std::cout owns lock std::endl;}else {std::cout doesnt own lock std::endl; // True} }//unique_lock可以延迟加锁 //可以延迟加锁 void defer_lock() {//延迟加锁std::unique_lockstd::mutex lock(mtx, std::defer_lock);if (lock.owns_lock()) {std::cout owns lock std::endl; // False}if (lock.owns_lock()) {std::cout owns lock std::endl;}else {std::cout doesnt own lock std::endl; // True}//可以加锁lock.lock();//可以自动析构解锁也可以手动解锁lock.unlock(); }//同时使用owns和defer void use_own_defer() {std::unique_lockstd::mutex lock(mtx);// 判断是否拥有锁if (lock.owns_lock()){std::cout Main thread has the lock. std::endl; // True}else{std::cout Main thread does not have the lock. std::endl;}std::thread t([]() {std::unique_lockstd::mutex lock(mtx, std::defer_lock);// 判断是否拥有锁if (lock.owns_lock()){std::cout Thread has the lock. std::endl;}else{std::cout Thread does not have the lock. std::endl;// True}// 加锁lock.lock();// 判断是否拥有锁if (lock.owns_lock()){std::cout Thread has the lock. std::endl; // // True}else{std::cout Thread does not have the lock. std::endl;}// 解锁lock.unlock();});lock.unlock();t.join(); } //unique_lock 结束 int main() {//use_unique();//owns_lock();//defer_lock();use_own_defer();return 0; }和lock_guard一样unique_lock也支持领养锁 //同样支持领养操作 void use_own_adopt() {mtx.lock();std::unique_lockstd::mutex lock(mtx, std::adopt_lock);if (lock.owns_lock()) {std::cout owns lock std::endl;}else {std::cout does not have the lock std::endl;}lock.unlock(); }尽管是领养的但是打印还是会出现owns lock因为不管如何锁被加上就会输出owns lock。既然unique_lock支持领养操作也支持延迟加锁那么可以用两种方式实现前文lock_guard实现的swap操作。 //之前的交换代码可以可以用如下方式等价实现 int a 10; int b 99; std::mutex mtx1; std::mutex mtx2; void safe_swap() {std::lock(mtx1, mtx2);std::unique_lockstd::mutex lock1(mtx1, std::adopt_lock);std::unique_lockstd::mutex lock2(mtx2, std::adopt_lock);std::swap(a, b);//错误用法//mtx1.unlock();//mtx2.unlock(); } void safe_swap2() {std::unique_lockstd::mutex lock1(mtx1, std::defer_lock);std::unique_lockstd::mutex lock2(mtx2, std::defer_lock);//需用lock1,lock2加锁std::lock(lock1, lock2);//错误用法//std::lock(mtx1, mtx2);std::swap(a, b); }大家注意一旦mutex被unique_lock管理加锁和释放的操作就交给unique_lock不能调用mutex加锁和解锁因为锁的使用权已经交给unique_lock了。我们知道mutex是不支持移动和拷贝的但是unique_lock支持移动当一个mutex被转移给unique_lock后可以通过unique_ptr转移其归属权. 注意延迟加锁和领养锁之后就只能使用后者进行解锁了不能使用原生的锁进行解锁操作 /转移互斥量所有权 //互斥量本身不支持move操作但是unique_lock支持 std::unique_lock std::mutex get_lock() {std::unique_lockstd::mutex lock(mtx);shared_data;return lock; } void use_return() {std::unique_lockstd::mutex lock(get_lock());shared_data; }锁的粒度表示加锁的精细程度一个锁的粒度要足够大保证可以锁住要访问的共享数据。同时一个锁的粒度要足够小保证非共享数据不被锁住影响性能。而unique_ptr则很好的支持手动解锁。 void precision_lock() {std::unique_lockstd::mutex lock(mtx);shared_data;lock.unlock();//不设计共享数据的耗时操作不要放在锁内执行std::this_thread::sleep_for(std::chrono::seconds(1));lock.lock();shared_data; }共享锁 试想这样一个场景对于一个DNS服务我们可以根据域名查询服务对应的ip地址它很久才更新一次比如新增记录删除记录或者更新记录等。平时大部分时间都是提供给外部查询对于查询操作即使多个线程并发查询不加锁也不会有问题但是当有线程修改DNS服务的ip记录或者增减记录时其他线程不能查询需等待修改完再查询。或者等待查询完线程才能修改。也就是说读操作并不是互斥的同一时间可以有多个线程同时读但是写和读是互斥的写与写是互斥的简而言之写操作需要独占锁。而读操作需要共享锁。 要想使用共享锁需使用共享互斥量std::shared_mutex,std::shared_mutex是C17标准提出的。C14标准可以使用std::shared_time_mutex, std::shared_mutex 和 std::shared_timed_mutex 都是用于实现多线程并发访问共享数据的互斥锁但它们之间存在一些区别 std::shared_mutex 提供了 lock(), try_lock(), 和 try_lock_for() 以及 try_lock_until() 函数这些函数都可以用于获 取互斥锁。提供了 try_lock_shared() 和 lock_shared() 函数这些函数可以用于获取共享锁。当 std::shared_mutex 被锁定后其他尝试获取该锁的线程将会被阻塞直到该锁被解锁。 std::shared_timed_mutex 与 std::shared_mutex 类似也提供了 lock(), try_lock(), 和 try_lock_for() 以及 try_lock_until() 函数用于获取互斥锁。与 std::shared_mutex 不同的是它还提供了 try_lock_shared() 和 lock_shared() 函数用于获取共享锁这些函数在尝试获取共享锁时具有超时机制。当 std::shared_timed_mutex 被锁定后其他尝试获取该锁的线程将会被阻塞直到该锁被解锁这与 std::shared_mutex 相同。然而当尝试获取共享锁时如果不能立即获得锁std::shared_timed_mutex 会设置一个超时超时过后如果仍然没有获取到锁则操作将返回失败。 C11标准没有共享互斥量可以使用boost提供的boost::shared_mutex。如果我们想构造共享锁可以使用std::shared_lock如果我们想构造独占锁, 可以使用std::lock_gurad.我们用一个类DNService代表DNS服务查询操作使用共享锁而写操作使用独占锁可以是如下方式的。 #include iostream #include memory #includemutex #includethread #includemap #include shared_mutex // std::shared_mutex(C17引入) std::shared_lock(C14引入) class DNService { public:DNService() {}//读操作采用共享锁std::string QueryDNS(std::string dnsname) {std::shared_lockstd::shared_mutex shared_locks(_shared_mtx);auto iter _dns_info.find(dnsname);if (iter ! _dns_info.end()) {return iter-second;}return ;}//写操作采用独占锁void AddDNSInfo(std::string dnsname, std::string dnsentry) {std::lock_guardstd::shared_mutex guard_locks(_shared_mtx);_dns_info.insert(std::make_pair(dnsname, dnsentry));} private:std::mapstd::string, std::string _dns_info;mutable std::shared_mutex _shared_mtx; };递归锁 有时候我们在实现接口的时候内部加锁接口内部调用完结束自动解锁。会出现一个接口调用另一个接口的情况如果用普通的std::mutex就会出现卡死因为嵌套加锁导致卡死。 #include iostream #include mutex #include threadclass BankAccount { private:std::mutex mtx;double balance 1000.0;public:// 接口1存款void deposit(double amount) {std::lock_guardstd::mutex lock(mtx);balance amount;std::cout Deposited amount , new balance: balance std::endl;}// 接口2取款void withdraw(double amount) {std::lock_guardstd::mutex lock(mtx);if (balance amount) {balance - amount;std::cout Withdrew amount , new balance: balance std::endl;} else {std::cout Insufficient funds for withdrawal of amount std::endl;}}// 接口3转账会调用存款和取款接口void transfer(BankAccount toAccount, double amount) {std::lock_guardstd::mutex lock(mtx); // 第一次加锁this-withdraw(amount); // 内部再次尝试加锁 - 这里会导致死锁!toAccount.deposit(amount);} };int main() {BankAccount accountA;BankAccount accountB;// 这个调用会导致死锁accountA.transfer(accountB, 100.0);return 0; }但是我们可以使用递归锁。 #include iostream #include mutexclass BankAccount { private:std::recursive_mutex mtx; // 关键修改使用可重入锁double balance 1000.0;public:void deposit(double amount) {std::lock_guardstd::recursive_mutex lock(mtx);balance amount;std::cout Deposited amount , new balance: balance std::endl;}void withdraw(double amount) {std::lock_guardstd::recursive_mutex lock(mtx);if (balance amount) {balance - amount;std::cout Withdrew amount , new balance: balance std::endl;}else {std::cout Insufficient funds for withdrawal of amount std::endl;}}void transfer(BankAccount toAccount, double amount) {std::lock_guardstd::recursive_mutex lock(mtx); // 第一次加锁this-withdraw(amount); // 内部再次加锁 - 现在可以正常工作toAccount.deposit(amount);} };int main() {BankAccount accountA;BankAccount accountB;accountA.transfer(accountB, 100.0);return 0; }但我个人并不推荐递归锁可以从设计源头规避嵌套加锁的情况我们可以将接口相同的功能抽象出来统一加锁。下面的设计演示了如何使用递归锁 //不推荐采用递归锁使用递归锁说明设计思路并不理想需优化设计 //推荐拆分逻辑将共有逻辑拆分为统一接口 #include iostream #include mutexclass BankAccount { private:std::mutex mtx; // 使用普通互斥量double balance 1000.0;// 不加锁的核心实现方法void unsafe_deposit(double amount) {balance amount;std::cout Deposited amount , new balance: balance std::endl;}// 不加锁的核心实现方法bool unsafe_withdraw(double amount) {if (balance amount) {balance - amount;std::cout Withdrew amount , new balance: balance std::endl;return true;}std::cout Insufficient funds for withdrawal of amount std::endl;return false;}public:// 线程安全的公共接口void deposit(double amount) {std::lock_guardstd::mutex lock(mtx);unsafe_deposit(amount);}void withdraw(double amount) {std::lock_guardstd::mutex lock(mtx);unsafe_withdraw(amount);}void transfer(BankAccount toAccount, double amount) {// 同时锁定两个账户避免死锁std::unique_lockstd::mutex lock1(mtx, std::defer_lock);std::unique_lockstd::mutex lock2(toAccount.mtx, std::defer_lock);std::lock(lock1, lock2); // 原子化加锁if (unsafe_withdraw(amount)) {toAccount.unsafe_deposit(amount);std::cout Transferred amount successfully std::endl;}} }; int main() {BankAccount accountA;BankAccount accountB;// 这个调用会导致死锁accountA.transfer(accountB, 100.0);return 0; }
http://www.pierceye.com/news/298353/

相关文章:

  • 网站是做推广好还是优化好广西大兴建设有限公司网站
  • 书籍教你如何做网站南阳定制网站制作价格低
  • 联合实验室 网站建设方案网站 手机兼容
  • 保定网站建设培训班团员团干部如何登录到系统
  • 做网站的旅行社手机页面网站模板怎么卖
  • 潮州南桥市场中国建设银行网站企业为什么要建设网站
  • 东营seo整站优化禁止wordpress历史版本
  • 太原网站建设与维护秦皇岛建设局
  • 我的世界做壁纸的网站学生班级优化大师
  • 高端大气上档次网站网站建立基本流程
  • 找人做网站如何担保江门网站建设
  • 张家界住房和城乡建设局网站各大网站提交入口网址
  • 张家港建网站Wordpress主页不要全部显示
  • 竞猜网站模板经典创意营销案例
  • 网站如何盈利流量费wordpress主题转html
  • html5做视频网站电脑制作h5最常用软件
  • 做印刷的网站有哪些百度网盟推广价格
  • 杭州网站seo优化国企央企都玩劳务外包
  • 杭州seo网站推广排名上市公司的信息网站
  • 做互联网网站的会抓西安小程序专业开发公司
  • 安徽省建设厅八大员报名网站网页设计兼职平台
  • 网站建设专利个人备案网站可以做商城展示
  • 北京做网站好的公司南充建设企业网站
  • 做一个静态网站要多少钱龙岗区网站建设
  • 安徽网站建设开发电话万网 网站模板
  • 网站响应式设计域名注册服务商
  • 焦作公司做网站小程序开发教程视频 推荐
  • php网站做代理服务器室内设计公司招聘
  • 做招标投标网站如何张家口专业做网站公司
  • 做网站广告中敏感词会涉及到工商彩票网站开发. 极云