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

如何在凡科上做网站高端网站开放

如何在凡科上做网站,高端网站开放,无敌在线观看免费完整版高清,龙岗高端网站建设目录 一.thread类的简单介绍 二.线程函数参数 三.原子性操作库(atomic) 四.lock_guard与unique_lock 1.lock_guard 2.unique_lock 五.条件变量 一.thread类的简单介绍 在C11之前#xff0c;涉及到多线程问题#xff0c;都是和平台相关的#xff0c;比如windows和linu…目录 一.thread类的简单介绍 二.线程函数参数  三.原子性操作库(atomic) 四.lock_guard与unique_lock 1.lock_guard 2.unique_lock 五.条件变量 一.thread类的简单介绍 在C11之前涉及到多线程问题都是和平台相关的比如windows和linux下各有自己的接 口这使得代码的可移植性比较差。C11中最重要的特性就是对线程进行支持了使得C在 并行编程时不需要依赖第三方库而且在原子操作中还引入了原子类的概念。要使用标准库中的 线程必须包含 thread 头文件。 函数名功能thread()构造一个线程对象没有关联任何线程函数即没有启动任何线程thread(fn, args1, args2, ...)构造一个线程对象并关联线程函数fnargs1args2...为线程函数的参数get_id()获取线程idjionable()线程是否还在执行joinable代表的是一个正在执行中的线程。jion()该函数调用后会阻塞住线程当该线程结束后主线程继续执行detach()在创建线程对象后马上调用用于把被创建线程与线程对象分离开分离的线程变为后台线程创建的线程的死活就与主线程无关 注意 1. 线程是操作系统中的一个概念线程对象可以关联一个线程用来控制线程以及获取线程的 状态。 2. 当创建一个线程对象后没有提供线程函数该对象实际没有对应任何线程。 get_id()的返回值类型为id类型id类型实际为std::thread命名空间下封装的一个类该类中 包含了一个结构体  // vs下查看 typedef struct { /* thread identifier for Win32 */void* _Hnd; /* Win32 HANDLE */unsigned int _Id; } _Thrd_imp_t; 3.当创建一个线程对象后并且给线程关联线程函数该线程就被启动与主线程一起运行。 线程函数一般情况下可按照以下三种方式提供 函数指针lambda表达式函数对象 #includeiostream #includethread #includestring using namespace std;void func1(string str) {cout str endl; } struct func2 {void operator()(string str){cout str endl;} };int main() {std::thread t1(func1, 函数指针);std::thread t2(func2(), 仿函数);std::thread t3([](string str){cout str endl; }, lambda);t1.join();t2.join();t3.join();return 0; } 4. thread类是防拷贝的不允许拷贝构造以及赋值但是可以移动构造和移动赋值即将一个 线程对象关联线程的状态转移给其他线程对象转移期间不意向线程的执行。 5. 可以通过jionable()函数判断线程是否是有效的如果是以下任意情况则线程无效 采用无参构造函数构造的线程对象线程对象的状态已经转移给其他线程对象线程已经调用jion或者detach结束 二.线程函数参数  线程函数的参数是以值拷贝的方式拷贝到线程栈空间中的因此即使线程参数为引用类型在 线程中修改后也不能修改外部实参因为其实际引用的是线程栈中的拷贝而不是外部实参。 如果想要通过形参改变外部实参时必须借助std::ref()函数,或者使用指针 #include thread void ThreadFunc1(int x) {x 10; } void ThreadFunc2(int* x) {*x 10; } int main() {int a 10;int b 10;// 如果想要通过形参改变外部实参时必须借助std::ref()函数thread t2(ThreadFunc1, std::ref(a));t2.join();cout a endl;//地址的拷贝thread t3(ThreadFunc2, b);t3.join();cout b endl;return 0; } 注意如果是类成员函数作为线程参数时必须将this作为线程函数参数。 三.原子性操作库(atomic) 多线程最主要的问题是共享数据带来的问题(即线程安全)。如果共享数据都是只读的那么没问 题因为只读操作不会影响到数据更不会涉及对数据的修改所以所有线程都会获得同样的数 据。但是当一个或多个线程要修改共享数据时就会产生很多潜在的麻烦。比如 两个线程分别进行100000次的操作 #include iostream #include thread using namespace std; unsigned long sum 0;void fun(size_t num) {for (size_t i 0; i num; i)sum; } int main() {cout Before joining,sum sum std::endl;thread t1(fun, 1000000);thread t2(fun, 1000000);t1.join();t2.join();cout After joining,sum sum std::endl;return 0; } 我们首先想到的解决办法就是加锁但是加锁有一个缺陷就是只要一个线程在对sum时其他线程就会被阻塞会影响程序运行的效率而且锁如果控制不好还容易造成死锁。 因此C11中引入了原子操作。所谓原子操作即不可被中断的一个或一系列操作C11引入 的原子操作类型使得线程间数据的同步变得非常高效原子操作头文件atomic。 例如 #include iostream #include thread #includeatomic using namespace std; //unsigned long sum 0; atomic_int sum 0;void fun(size_t num) {for (size_t i 0; i num; i)sum; } int main() {cout Before joining,sum sum std::endl;thread t1(fun, 1000000);thread t2(fun, 1000000);t1.join();t2.join();cout After joining,sum sum std::endl;return 0; } 在C11中程序员不需要对原子类型变量进行加锁解锁操作线程能够对原子类型变量互斥的 访问。 更为普遍的程序员可以使用atomic类模板定义出需要的任意原子类型。 atmoicT t;   // 声明一个类型为T的原子类型变量t #include atomic int main() { atomicint a1(0); //atomicint a2(a1);  // 编译失败 atomicint a2(0); //a2 a1;        // 编译失败 return 0; } 注意原子类型通常属于资源型数据多个线程只能访问单个原子类型的拷贝因此在C11 中原子类型只能从其模板参数中进行构造不允许原子类型进行拷贝构造、移动构造以及 operator等为了防止意外标准库已经将atmoic模板类中的拷贝构造、移动构造、赋值运算 符重载默认删除掉了。 四.lock_guard与unique_lock 在多线程环境下如果想要保证某个变量的安全性只要将其设置成对应的原子类型即可即高 效又不容易出现死锁问题。但是有些情况下我们可能需要保证一段代码的安全性那么就只能 通过锁的方式来进行控制。 比如一个线程对变量number进行加一100次另外一个减一100次每次操作加一或者减一之 后输出number的结果要求number最后的值为1。  #include thread #include mutex int number 0; mutex g_lock; int ThreadProc1() {for (int i 0; i 100; i){g_lock.lock();number;cout thread 1 : number endl;g_lock.unlock();}return 0; } int ThreadProc2() {for (int i 0; i 100; i){g_lock.lock();--number;cout thread 2 : number endl;g_lock.unlock();}return 0; }int main() {thread t1(ThreadProc1);thread t2(ThreadProc2);t1.join();t2.join();cout number: number endl;system(pause);return 0; } 上述代码的缺陷锁控制不好时可能会造成死锁最常见的比如在锁中间代码返回或者在锁 的范围内抛异常。因此C11采用RAII的方式对锁进行了封装即lock_guard和unique_lock。 lock_guard定义如下 templateclass _Mutex class lock_guard { public:// 在构造lock_gard时_Mtx还没有被上锁explicit lock_guard(_Mutex _Mtx): _MyMutex(_Mtx){_MyMutex.lock();}// 在构造lock_gard时_Mtx已经被上锁此处不需要再上锁lock_guard(_Mutex _Mtx, adopt_lock_t): _MyMutex(_Mtx){}~lock_guard() _NOEXCEPT{_MyMutex.unlock();}lock_guard(const lock_guard) delete;lock_guard operator(const lock_guard) delete; private:_Mutex _MyMutex; }; 1.lock_guard 通过上述代码可以看到lock_guard类模板主要是通过RAII的方式对其管理的互斥量进行了封 装在需要加锁的地方只需要用上述介绍的任意互斥体实例化一个lock_guard调用构造函数 成功上锁出作用域前lock_guard对象要被销毁调用析构函数自动解锁可以有效避免死锁 问题。 改造上述代码 #include thread #include mutex int number 0; mutex g_lock; int ThreadProc1() {for (int i 0; i 100; i){lock_guardmutex lock(g_lock);//调用构造加锁出作用域自动解锁number;cout thread 1 : number endl;}return 0; } int ThreadProc2() {for (int i 0; i 100; i){lock_guardmutex lock(g_lock);//调用构造加锁出作用域自动解锁--number;cout thread 2 : number endl;}return 0; }int main() {thread t1(ThreadProc1);thread t2(ThreadProc2);t1.join();t2.join();cout number: number endl;system(pause);return 0; } lock_guard的缺陷太单一用户没有办法对该锁进行控制因此C11又提供了unique_lock。 2.unique_lock 与lock_gard类似unique_lock类模板也是采用RAII的方式对锁进行了封装并且也是以独占所有权的方式管理mutex对象的上锁和解锁操作即其对象之间不能发生拷贝。在构造(或移动(move)赋值)时unique_lock 对象需要传递一个 Mutex 对象作为它的参数新创建的unique_lock 对象负责传入的 Mutex 对象的上锁和解锁操作。使用以上类型互斥量实例化unique_lock的对象时自动调用构造函数上锁unique_lock对象销毁时自动调用析构函数解锁可以很方便的防止死锁问题。  与lock_guard不同的是unique_lock更加的灵活提供了更多的成员函数 上锁/解锁操作lock、try_lock、try_lock_for、try_lock_until和unlock。修改操作移动赋值、交换(swap与另一个unique_lock对象互换所管理的互斥量所有权)、释放(release返回它所管理的互斥量对象的指针并释放所有权)。获取属性owns_lock(返回当前对象是否上了锁)、operator bool()(与owns_lock()的功能相同)、mutex(返回当前unique_lock所管理的互斥量的指针)。 五.条件变量 对条件变量的熟悉我们linux互斥与同步已经讲过了他们用来进行线程之间的互相通知。condition_variable和Linux posix的条件变量并没有什么大的区别主要还是面向对象实现的。 例如使用两个线程两个线程交替打印奇数和偶数 #includemutex #includecondition_variable mutex g_lock;//锁 condition_variable cond;//条件变量int num 1;//打印奇数 void Func1(int n) {for (int i 1; i n; i){unique_lockmutex mutex(g_lock);if (num % 2 0){cond.wait(mutex);}cout thread1: num endl;cond.notify_one();} }//打印偶数 void Func2(int n) {for (int i 1; i n; i){unique_lockmutex mutex(g_lock);if (num % 2 1){cond.wait(mutex);}cout thread2: num endl;cond.notify_one();} } int main() {thread t1(Func1, 100);thread t2(Func2, 100);t1.join();t2.join();return 0; }
http://www.zqtcl.cn/news/327480/

相关文章:

  • seo网站优化推广怎么做龙岗中心医院
  • 建网站程序智能网站建设平台
  • 建筑公司分几级资质seo入门培训
  • wap类网站上海网站建设免费推
  • 网站建设哪家好公司建设银行网站怎么登陆不
  • 关于建设网站的需求wordpress不能发布文章
  • 如何一键建淘宝客网站中国建设银行金华分行网站
  • 给wordpress添加公告英语seo
  • 佛山市网站建设系统wap浏览器网页版
  • 关于小说网站的一些建设流程学做蛋糕有哪些网站
  • 益阳购物网站开发设计禹城网站制作
  • 教育网站开发文档全网营销推广案例
  • 最流行的网站开发框架wordpress阅读权限
  • 怎么做推广网站创立网站
  • 制作自己的网站需要什么材料网站计费系统怎么做
  • 网站和域名的区别昆山网站开发建设公司
  • 兼职网站推广如何做西安市商标局
  • 打开网站说建设中是什么问题莱芜金点子招小时工
  • 做网站的相关协议秦皇岛解封最新消息今天
  • 网站托管维护方案新闻媒体发稿平台
  • 网站扩展名四平网站建设怎么选
  • 网站制作价格与售后视频网站建设有什么意义
  • 网站建设+太原1核1g可以做几个网站
  • 电商设计网站有哪些内容西安百度推广外包
  • 深圳网站建设价格多少做废旧金属的网站
  • wordpress 文档超级优化空间
  • 湖北seo网站推广官方网站怎么制作
  • 随州网站seo诊断wordpress 只显示一个主题
  • 建站登录可信网站认证 费用
  • 互站网站源码用jsp做网站一般会用到什么