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

苏州做网站海口建设企业网站

苏州做网站,海口建设企业网站,网页设计与制作教程,凡科做网站要钱目录 1. cpp11-> std::condition_variable 2. this_thread::sleep_for 3. 经典问题: 两个线程相互打印偶数和奇数 1. cpp11-> std::condition_variable 基本和 posix 提供的条件变量是一样的. 里面有两个核心操作: wait(等待)notify(唤醒) 注意: 条件变量本身不是线…

目录

1. cpp11-> std::condition_variable

2. this_thread::sleep_for

3. 经典问题: 两个线程相互打印偶数和奇数


1. cpp11-> std::condition_variable

基本和 posix 提供的条件变量是一样的. 里面有两个核心操作:

  • wait(等待)
  • notify(唤醒)

注意: 条件变量本身不是线程安全的, 所以它本身也需要互斥锁的保护.

我们下面介绍一下 c++11 里面条件变量两个接口:

  • wait: 阻塞的意思 -> 解锁 + 阻塞, 直到 notify.

The execution of the current thread (which shall have locked lck's mutex) is blocked until notified.
At the moment of blocking the thread, the function automatically calls lck.unlock(), allowing other locked threads to continue.
Once notified (explicitly, by some other thread), the function unblocks and calls lck.lock(), leaving lck in the same state as when the function was called. Then the function returns (notice that this last mutex locking may block again the thread before returning).

  • notify: 是唤醒的意思

Notify one

Unblocks one of the threads currently waiting for this condition.
If no threads are waiting, the function does nothing.
If more than one, it is unspecified which of the threads is selected.

Notify all

Unblocks all threads currently waiting for this condition.
If no threads are waiting, the function does nothing.

好的, 我们下面继续看看文档上怎么举得例子:

// condition_variable example
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variablestd::mutex mtx;
std::condition_variable cv;
bool ready = false;void print_id(int id) {std::unique_lock<std::mutex> lck(mtx);while (!ready) cv.wait(lck);// ...std::cout << "thread " << id << '\n';
}void go() {std::unique_lock<std::mutex> lck(mtx);ready = true;cv.notify_all();
}int main()
{std::thread threads[10];// spawn 10 threads:for (int i = 0; i < 10; ++i)threads[i] = std::thread(print_id, i);std::cout << "10 threads ready to race...\n";go();                       // go!for (auto& th : threads) th.join();return 0;
}

啥意思呢上面代码?

首先, 它弄了一个数组, 每个元素都是一个空壳的 thread, 只有空间没有实际的值哦~

然后 for 循环, 依次对这十个空壳的 thread 发生移动构造, 是用临时变量 std::thread(print_id, i) 来进行移动构造, 每个线程会立刻去执行print_id, 每个线程来到 print_id 之后, 会先加锁, 然后十个线程里抢到锁的执行 while , wait 一下, 归还锁, 然后剩下 9 个线程依次.... 理论上, 时间足够的话, 所有的线程都会到达 wait.

然后主线程同时继续向下运行, 把 ready = true. 所有的线程继续竞争锁, 竞争到的出 while 然后打印自己的 id 值... 以此类推.

我们看, 当10个线程起来了之后, 对于每一个线程来说, 要么你抢不到锁, 然后就会阻塞在 12 行, 要么你比较幸运抢到了锁, 然后wait.
理论上, 只要时间比较长, 应该所有线程到最后都会跑到 13 行进行wait等待.
然后, 上面代码来到go()函数, 先弄了一个锁, 然后把所有的线程唤醒.
有没有可能在go()之前, 还有一些线程没有进入wait状态呢?
有可能. 也有可能有些线程不会进入wait状态, 直接掠过while(!ready)来到206行进行打印.
我们执行一下: ... 发现0号线程最容易第一个打印.
我们为了让他都进入wait()阻塞, 我们用一下sleep.

2. this_thread::sleep_for

我们下面介绍一个 sleep_for() 它可以让线程等待休眠一段时间再继续运行, 这样的话我们让主线程等几百毫秒, 等所有的线程到到达再进行竞争更加公平一些.

Sleep for time span

Blocks execution of the calling thread during the span of time specified by rel_time.

The execution of the current thread is stopped until at least rel_time has passed from now. Other threads continue their execution.

然后, 他的一些时间定义在 duration 类当中, 我们下面来看一下:

Duration

A duration object expresses a time span by means of a count and a period.

Internally, the object stores the count as an object of member type rep (an alias of the first template parameter, Rep), which can be retrieved by calling member function count.

This count is expresed in terms of periods. The length of a period is integrated in the type (on compile time) by its second template parameter (Period), which is a ratio type that expresses the number (or fraction) of seconds that elapse in each period.

我们再继续运行一下上面的程序, 不过是在主线程加上 sleep_for, 发现更加随机一些了:

3. 经典问题: 两个线程相互打印偶数和奇数

这个地方有一个经典的问题:
两个线程交替打印, 一个打印奇数, 一个打印偶数. 所以, 他需要一个线程打印完了, 就通知另一个线程再打印偶数, 再来回交替的.

约定: 我们为了好写代码, 我们规定 th1 打印偶数, 从 0 开始打印, 0, 2, 4 ..., 然后 th2 打印奇数, 从 1 开始打印, 1, 3, 5 ... 整体的打印逻辑是 th1 先打印 0, th2 再打印 1, th1 再打印 2, th2 打印 3... 直到 99.

#include<thread>
#include<iostream>
#include<mutex>
#include<condition_variable>
using namespace std;mutex mtx;
condition_variable c;
int flag = false;void pinrtOddNumber(int n)
{int i = 1;while (i < n){unique_lock<mutex> lg(mtx); // 加锁while (!flag) // 是false的时候会被wait. c.wait(lg);cout << "th2(odd): " << i << endl; // 临界资源!!! flag = false;i += 2;c.notify_one(); // 唤醒}
}void pinrtEvenNumber(int n)
{int i = 0;while (i < n){unique_lock<mutex> lg(mtx); // 加锁while (flag) // true的时候会被wait()c.wait(lg);cout << "th1(eve): " << i << endl; // 临界资源!!! flag = true;i += 2;c.notify_one(); // 唤醒}
}int main()
{thread t1(pinrtEvenNumber, 100);thread t2(pinrtOddNumber, 100);t1.join();t2.join();return 0;
}

我们看一下结果:

下面说一下细节:

  • while() wait() 是做什么的? 是为了防止奇数先打印 或者是 防止有一个连续打印的.
  • c.notify_one(); 这个的意义是啥? 首先一个在休眠吧? 还有一个因为自己把 flag 设置了, 所以等会儿自己也会休眠, 所以这个快休眠的在自己休眠之前先唤醒一下另一个线程.

不过还有一种用 lambda 写法, 感觉是一样的, 只是写法上不同而已.

#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>void two_thread_print() {std::mutex mtx;std::condition_variable c;int n = 100;bool flag = true;std::thread t1([&]() {int i = 0;while (i < n) {std::unique_lock<std::mutex> lock(mtx); // 加锁c.wait(lock, [&]() -> bool { return flag; }); // 是否还锁? std::cout << i << std::endl; // 打印flag = false; // 设置falg. i += 2; // 偶数c.notify_one(); // 唤醒}});std::thread t2([&]() {int j = 1;while (j < n) {std::unique_lock<std::mutex> lock(mtx);c.wait(lock, [&]() -> bool { return !flag; });std::cout << j << std::endl;j += 2; // 奇数flag = true;c.notify_one();}});t1.join();t2.join();
}int main() 
{two_thread_print();return 0;
}

文章转载自:

http://SnJXTzGH.Lssfd.cn
http://vWpe20co.Lssfd.cn
http://vMzZGFKx.Lssfd.cn
http://rB3d0b0c.Lssfd.cn
http://DOsyR3Cq.Lssfd.cn
http://IHvyy2iT.Lssfd.cn
http://X7IV5U7y.Lssfd.cn
http://ch5V0d4L.Lssfd.cn
http://gU0LGrqx.Lssfd.cn
http://DUIZM8Z3.Lssfd.cn
http://eMdgwHyu.Lssfd.cn
http://5u1TUU2h.Lssfd.cn
http://vUHYF755.Lssfd.cn
http://YilHK1LJ.Lssfd.cn
http://LEISLKB7.Lssfd.cn
http://pWudhz74.Lssfd.cn
http://pz3sX8jN.Lssfd.cn
http://KMKm4OKW.Lssfd.cn
http://97R63BBr.Lssfd.cn
http://kg9J4T5a.Lssfd.cn
http://BhOG7aoJ.Lssfd.cn
http://YOnk1czq.Lssfd.cn
http://aR29et6J.Lssfd.cn
http://sOuksfxi.Lssfd.cn
http://lY69Wz2o.Lssfd.cn
http://r1nKIRt5.Lssfd.cn
http://GqyElJD2.Lssfd.cn
http://TlYSoiJU.Lssfd.cn
http://eJ4ykI2i.Lssfd.cn
http://Q8nCbs4i.Lssfd.cn
http://www.dtcms.com/wzjs/764920.html

相关文章:

  • 3d打印网站开发dedecms网站怎么搬家
  • 安仁做网站wordpress点击分享功能
  • 成都网站品牌设计ftp 网站
  • 创建自己的网站需要准备什么网站建设公司导航
  • 微网站开发框架企业网站怎么收录
  • 网泰网站建设网络wordpress做微信登录页面
  • 重庆企业网站制作外包青岛网站设计报价
  • 静态网站模板上海民政网站相关建设情况
  • 校园网站建设初探论文企业管理网站
  • 宁波中小企业网站制作网赢做网站怎么样
  • 网站建设服务规划与措施网站建设的方案图片
  • 自适应网站模板建站wordpress 资源站主题
  • 濮阳做公司网站龙华网站建设哪家公司好
  • 青岛市工程建设信息网站教育网站建站需求
  • 上海优秀网站设计wordpress主机 好吗
  • 做网站怎么租个空间网络营销课程总结范文
  • 苏州手机网站开发公司教务系统管理系统入口
  • 网站制作案例怎么样怎样在设计网站做图赚钱吗
  • 建设网站网站威海 医院网站建设
  • 网站建设人员性格网络营销专业就业
  • 网站续费 多久wordpress主题video
  • 连云港网站关键词优化服务网站建设合同服务内容
  • vps网站解析域名加速百度对网站文章的收录
  • 免费发布信息网站怎么让网站绑定域名
  • 健康管理公司网站建设罗岗网站建设哪家好
  • 美术馆网站建设概述襄阳seo顾问
  • 建设银行黑龙江省分行官方网站建html5响应式网站的工具
  • 如何弄死一个网站灌南县建设局网站
  • 做网站的那家公司好推广普通话手抄报文字
  • 石家庄网站制作公司哪家好北欧做的比较好的网站