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

网络代理ipseo视频教学网站

网络代理ip,seo视频教学网站,网站跳转到另外一个网站怎么做,做网站能挣钱么文章目录一、用互斥保护共享数据1.std::mutex调用lock()加锁,unlock()解锁2.std::lock_guard利用RAII机制保证发生异常时也能正常unlock二、防范死锁1.std::lock同时锁住多个互斥2.std::adopt_lock指明互斥已被锁住,不得在构造函数内试图另行加锁3.C17实…

文章目录

  • 一、用互斥保护共享数据
    • 1.std::mutex调用lock()加锁,unlock()解锁
    • 2.std::lock_guard利用RAII机制保证发生异常时也能正常unlock
  • 二、防范死锁
    • 1.std::lock同时锁住多个互斥
    • 2.std::adopt_lock指明互斥已被锁住,不得在构造函数内试图另行加锁
    • 3.C++17实现了std::scoped_lock模板,是std::lock模板的RAII实现
    • 4.防范死锁的准则
      • 1.避免嵌套锁
      • 2.一旦持锁,就须避免调用用户提供的程序接口
      • 3.依从固定顺序获取锁
    • 5.std::unique_lock灵活加锁
      • 1.std::unique_lock第二个参数使用默认值
      • 2.std::unique_lock第二个参数传入std::adopt_lock指明互斥已经lock过,std::unique_lock据此接收锁的归属权,不得在构造函数中试图另行加锁。
      • 3.std::unique_lock第二个参数传入std::defer_lock指明互斥处于无锁状态,等以后有需要的时候再调用std::unique_lock对象的lock()加锁
      • 3.在不同作用域转移互斥所有权,std::unique_lock可移动不可复制
    • 6.按适当粒度加锁
    • 7.在初始化过程中保护共享数据,std::call_once()
      • 1.类的数据成员线程安全的延迟初始化
      • 2.单例模式
        • 1.new生成对象指针,使用std::call_once保证只执行一次初始化
        • 2.C++11静态变量初始化,只会在某一个线程单独发生


一、用互斥保护共享数据

1.std::mutex调用lock()加锁,unlock()解锁

2.std::lock_guard利用RAII机制保证发生异常时也能正常unlock

#include <list>
#include <mutex>
#include <algorithm>
#include <iostream>
#include <thread>
std::list<int> some_list;
std::mutex some_mutex;void add_to_list(int new_value)
{std::lock_guard<std::mutex> guard(some_mutex);some_list.push_back(new_value);
}
bool list_contains(int value_to_find)
{std::lock_guard<std::mutex> guard(some_mutex);return std::find(some_list.begin(),some_list.end(),value_to_find)!= some_list.end();
}int main()
{std::thread t(add_to_list,42); list_contains(42);t.join();std::cin.get();
}

二、防范死锁

1.std::lock同时锁住多个互斥

2.std::adopt_lock指明互斥已被锁住,不得在构造函数内试图另行加锁

代码如下(示例):

#include <mutex>class some_big_object
{};void swap(some_big_object& lhs,some_big_object& rhs)
{}class X
{
private:some_big_object some_detail;mutable std::mutex m;
public:X(some_big_object const& sd):some_detail(sd){}friend void swap(X& lhs, X& rhs){if(&lhs==&rhs)return;std::lock(lhs.m,rhs.m);std::lock_guard<std::mutex> lock_a(lhs.m,std::adopt_lock);std::lock_guard<std::mutex> lock_b(rhs.m,std::adopt_lock);swap(lhs.some_detail,rhs.some_detail);}
};int main()
{}

3.C++17实现了std::scoped_lock模板,是std::lock模板的RAII实现

    friend void swap(X& lhs, X& rhs){if(&lhs==&rhs)return;std::scoped_lock(lhs.m,rhs.m);swap(lhs.some_detail,rhs.some_detail);}

4.防范死锁的准则

1.避免嵌套锁

假如已经持有锁就应该避免获取第二个锁,万一有确有需求获取多个锁,应采用std::lock模板,借单独的调用动作一次获取全部锁来避免死锁。

2.一旦持锁,就须避免调用用户提供的程序接口

我们已经持有锁,再去调用用户实现的接口,恰好用户接口内部试图获取锁,就可能发生嵌套锁,不过有时这样是在所难免,所以我们又需要另一个新的准则。

3.依从固定顺序获取锁

如果多个锁是必要的,又无法通过std::lock模板在一部操作中完成,我们只能退而求其次,在每个线程内都依从固定的顺序获取这些锁。

5.std::unique_lock灵活加锁

与std::lock_guard比较,std::unique_lock即能很好利用RAII机制,又更加的灵活,可以根据需要,在std::unique_lock对象构造时对mutex对象加锁,也可以在std::unique_lock构造时使mutex处于无锁状态,之后调用std::unique_lock对象的lock()函数择机加锁,也可以接管已经加过锁的mutex,且允许在std::unique_lock对象销毁前调用std::unique_lock的成员函数unlock()解锁。

1.std::unique_lock第二个参数使用默认值

std::mutex m;
void f()
{std::unique_lock<std::mutex> lk(m);//构造时加锁//.....处理共享数据的事务lk.unlock();//解锁//.....处理非共享数据的事务lk.lock();//加锁//.....处理共享数据的事务
}

2.std::unique_lock第二个参数传入std::adopt_lock指明互斥已经lock过,std::unique_lock据此接收锁的归属权,不得在构造函数中试图另行加锁。

std::mutex m;
void f()
{m.lock();//互斥已经加锁std::unique_lock<std::mutex> lk(m,std::adopt_lock);//指明互斥已经加过锁//.....lk.unlock();
}

3.std::unique_lock第二个参数传入std::defer_lock指明互斥处于无锁状态,等以后有需要的时候再调用std::unique_lock对象的lock()加锁

std::mutex m;
void f()
{std::unique_lock<std::mutex> lk(m,std::defer_lock);//构造时无锁状态lk.lock();//延后加锁//...lk.unlock();//....
}

3.在不同作用域转移互斥所有权,std::unique_lock可移动不可复制

准许函数锁定互斥,然后将互斥所有权转移给函数调用者,好让他在一个锁的作用下执行其它操作。

std::mutex m;
std::unique_lock<std::mutex> f()
{std::unique_lock<std::mutex> lk(m);return lk;
}
void hold()
{std::unique_lock<std::mutex> lk(f());std::cout << __FUNCTION__ << std::endl; 
}

6.按适当粒度加锁

只在必要的操作上加锁,避免必要操作外加锁

7.在初始化过程中保护共享数据,std::call_once()

1.类的数据成员线程安全的延迟初始化

#include <mutex>struct connection_info
{};struct data_packet
{};struct connection_handle
{void send_data(data_packet const&){}data_packet receive_data(){return data_packet();}
};struct remote_connection_manager
{connection_handle open(connection_info const&){return connection_handle();}
} connection_manager;class X
{
private:connection_info connection_details;connection_handle connection;std::once_flag connection_init_flag;void open_connection(){connection=connection_manager.open(connection_details);}
public:X(connection_info const& connection_details_):connection_details(connection_details_){}void send_data(data_packet const& data){std::call_once(connection_init_flag,&X::open_connection,this);connection.send_data(data);}data_packet receive_data(){std::call_once(connection_init_flag,&X::open_connection,this);return connection.receive_data();}
};int main()
{}

2.单例模式

1.new生成对象指针,使用std::call_once保证只执行一次初始化

#include <iostream>
#include <thread>
#include <memory>
#include <mutex>
#include <chrono> class X
{
private:X() {};static void init() {static huishou hs;x = new X();std::cout << "调用std::call_once的线程ID: " << std::this_thread::get_id() << std::endl;}
public:static X* getMe(){std::call_once(X::init_flag,X::init);return x;}void print(){std::lock_guard<std::mutex> lk(m);std::cout << "单例对象地址:"<< this << " 当前线程ID: " << std::this_thread::get_id() << std::endl;}private:class huishou{public:huishou() {};~huishou() {delete X::x;};};static X* x;static std::once_flag init_flag;std::mutex m;	
};X* X::x = nullptr;
std::once_flag X::init_flag;void f()
{X* x = X::getMe();x->print();
}
int main()
{std::thread t1(f);std::thread t2(f);std::thread t3(f);std::thread t4(f);t1.join();t2.join();t3.join();t4.join();
}

2.C++11静态变量初始化,只会在某一个线程单独发生

#include <iostream>
#include <thread>
#include <memory>
#include <mutex>
#include <chrono> class X
{
private:X() {};
public:static X& getMe(){static X x;return x;}void print(){std::lock_guard<std::mutex> lk(m);std::cout << "单例对象地址:"<< this << " 当前线程ID: " << std::this_thread::get_id() << std::endl;}
private:std::mutex m;	
};void f()
{X& x = X::getMe();x.print();
}
int main()
{std::thread t1(f);std::thread t2(f);std::thread t3(f);std::thread t4(f);t1.join();t2.join();t3.join();t4.join();
}

http://www.lbrq.cn/news/2629603.html

相关文章:

  • 网站的评测系统怎么做的源码时代培训机构官网
  • 正规刷手机单做任务网站网络推广怎么推广
  • 外包网站都有哪些品牌宣传推广策划方案
  • 静态网站制作模板宣传推广计划怎么写
  • 简单网站开发实例教程乐清网站建设
  • freedns免费域名申请seo推广seo技术培训
  • 怎么做婚庆网站平台网络优化行业的发展前景
  • 武汉装修网站建设it培训机构哪个好一点
  • app和网站开发电脑学校培训
  • 怎么做整人点不完的网站口碑营销理论
  • python做网站有优势智能建站网站模板
  • 初级网站建设百度置顶广告多少钱
  • 自己搭建云手机服务器杭州seo关键词优化公司
  • 做网站开发要学什么软件无锡做网站的公司
  • 网站设计ps做效果图过程萧山区seo关键词排名
  • bex5可以做网站吗如何做好网络营销工作
  • 中牟网站推广阿里云注册域名
  • 投资网站建设百度在线识图查图片
  • 招聘类网站怎么做人工智能培训机构排名前十
  • 临沂医院网站建设cms网站
  • 上城区网站建设价格黄页
  • pc站和手机网站爱战网关键词查询网站
  • 南山网站设计电话网络营销理论
  • 网站二级目录 修改路径关键词收录查询工具
  • 酒店网站建设 源码产品软文范例1000字
  • 地图上如何添加自己公司的地址网站seo优化发布高质量外链
  • 郑州做网站公司有哪些百度帐号
  • 网站统计工具是什么意思长沙seo外包服务
  • 南宁3及分销网站制作seo技术培训山东
  • 榆次做网站搭建一个网站需要多少钱?
  • Docker Buildx最佳实践:多架构镜像构建指南
  • 鸿蒙 - 分享功能
  • 超高车辆如何影响城市立交隧道安全?预警系统如何应对?
  • libpq库使用
  • leetcode-python-删除链表的倒数第 N 个结点
  • 【Linux】特效爆满的Vim的配置方法 and make/Makefile原理