C++11多线程编程(常见面试题)
【题目1】
子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码
【题解】
首先我们来分析一下这道题...(是个刚入门的小白,分析的不好请见谅)
1、由于子线程需要循环10次不受主线程干扰,而主线程需要循环100次不受子线程干扰,所以显然,在他们进入循环的时候需要一个锁把这段循环锁住,不然会导致资源被抢占(此处的资源可以理解为是循环里的cout)。(其实简单来说互斥量是为了保证子线程和主线程的for不同时进行)
2、然后问题来了,怎么控制子线程循环后主线程循环,然后一直这样依次循环呢?条件变量就可以做到这点,我们可以通过改变某个全局变量的值,第一次将该全局变量置为10,也就是说我们只要控制如果传入的参数和该全局变量不等,就让他一直等待,当执行完子线程的循环后改变这个全局变量为100,那么对于子线程来说全局变量和传入的参数就不相等了,那么条件变量就会一直等待。当然如果一直让他等待肯定是不对的,所以当一个线程执行完循环之后需要唤醒这个条件变量,告诉线程变量已经改变又可以开始抢资源啦。(其实条件变量就是为了控制子主线程运行的先后条件)
【代码】
#include<thread>
#include<iostream>
#include<cstdio>
#include<mutex>
#include<condition_variable>
using namespace std;
int flag = 10;
mutex mu;
condition_variable cv;
void fun(int x, char c)
{
for (int i = 0; i < 50; i++)
{
unique_lock<mutex> lock(mu);
while(flag != x)
cv.wait(lock);//在该线程阻塞之前会执行lock.unlock,这样别的线程才不会被锁住
for (int j = 0; j < x; j++)
cout << c << ":" << j << endl;
flag = (x == 10)? 100 : 10;
cv.notify_one();
}
}
int main()
{
thread t1(fun, 10, 'A');
fun(100, 'B');
t1.join();
}
【总结】
理解这段代码的时候,被wait()弄了好久,可能是我太蠢qwq那么来说一下wait()吧,我们分两种情况来说。
(1)一开始,主线程先抢到了锁
那么就会判断flag是否等于x,很显然如果是主线程先拿到锁此时flag=10,x=100不等,那么这个时候主线程就会执行wait(),也就是会被阻塞,然后因为wait()自身有这样一个机制(当他执行的时候会自动释放锁吗,也就是会自动执行unlock,给其他线程一个拿锁的机会),这个时候子线程就会拿到锁,并且判断fag是否等于x,这时候明显是相等的,那么就会进行下面的一系列循环,这个时候重点来了,一定要改变全局变量!!如果不改变会是什么结果呢?假设我们把那句话注释掉直接执行notify_one(),那么主线程就会被唤醒它的wait()又会自动参与抢锁,由于flag没有改变,那么flag和x的值还是相等,所以它依然会被阻塞,那么依旧就是子线程执行,就不满足题意了。
(2)一开始,子线程先抢到了锁
因为满足flag=x,那么会执行接下来的for,按部就班改个flag,然后唤醒被wait的线程(这时候其实没有),因为执行完一个循环,uniqie_lock会自动释放锁,然后子线程和主线程就又开始抢锁了,这次我们假设还是子线程先抢到了锁,但由于修改了flag,此时flag!=x,子线程就被阻塞,然后就和情况(1)差不多啦。
【题目2】
编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
【题解】
其实只要理解了上一题,就是一个套路啦。这里有所不同的是有3个线程,所以最后唤醒条件变量的时候记得用notify_all()。
【代码】
#include<thread>
#include<iostream>
#include<cstdio>
#include<mutex>
#include<condition_variable>
using namespace std;
int flag = 0;
mutex mu;
condition_variable cv;
void fun(int x)
{
for (int i = 0; i < 10; i++)
{
unique_lock<mutex>lock(mu);
while (x != flag)
cv.wait(lock);
cout << static_cast<char>('A' + x) << " ";
flag = (flag + 1) % 3;
cv.notify_all();
}
}
int main()
{
thread t1(fun, 1);
thread t2(fun, 2);
fun(0);
t1.join();
t2.join();
}
C++11多线程编程(常见面试题)的更多相关文章
- 整理的最全 python常见面试题(基本必考)
整理的最全 python常见面试题(基本必考) python 2018-05-17 作者 大蛇王 1.大数据的文件读取 ① 利用生成器generator ②迭代器进行迭代遍历:for line in ...
- 整理的最全 python常见面试题
整理的最全 python常见面试题(基本必考)① ②③④⑤⑥⑦⑧⑨⑩ 1.大数据的文件读取: ① 利用生成器generator: ②迭代器进行迭代遍历:for line in file; 2.迭代 ...
- 【转载】JAVA常见面试题及解答(精华)
JAVA常见面试题及解答(精华) 1)transient和volatile是java关键字吗?(瞬联) 如果用transient声明一个实例变量,当对象存储时,它的值不需要维持.例如: ...
- 【javascript常见面试题】常见前端面试题及答案
转自:http://www.cnblogs.com/syfwhu/p/4434132.html 前言 本文是在GitHub上看到一个大牛总结的前端常见面试题,很多问题问的都很好,很经典.很有代表性.上 ...
- java常见面试题及答案 1-10(基础篇)
java常见面试题及答案 1.什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"? Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程.Java 源文件被 ...
- iOS常见面试题汇总
iOS常见面试题汇总 1. 什么是 ARC? (ARC 是为了解决什么问题而诞生的?) ARC 是 Automatic Reference Counting 的缩写, 即自动引用计数. 这是苹果在 i ...
- java常见面试题及答案
java常见面试题及答案 来源 https://blog.csdn.net/hsk256/article/details/49052293 来源 https://blog.csdn.net/hsk25 ...
- Java 常见面试题(一)
1)什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Java虚拟机执行的字节码文件.Java被设 ...
- 夯实Java基础系列16:一文读懂Java IO流和常见面试题
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- 【搞定 Java 并发面试】面试最常问的 Java 并发基础常见面试题总结!
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.欢迎 Sta ...
随机推荐
- SVG path d Attribute
Scalable Vector Graphics (SVG) 1.1 (Second Edition) W3C Recommendation 16 August 2011 http://www.w3. ...
- how to input special symbol in macOS
how to input special symbol in macOS 如何在 macOS 中输入特殊符号 1024 ≈ 1000 2^10 == 1024 约等于 1000, 方便用来表示 Opt ...
- free open music API all in one
free open music API all in one music API SoundCloud xgqfrms · free https://w.soundcloud.com/player/? ...
- Google & Chrome console & text adventure game
Google & Chrome console & text adventure game Google's text adventure game https://www.googl ...
- TDD & Unit testing
TDD & Unit testing TDD jest https://github.com/facebook/jest https://facebook.github.io/jest/zh- ...
- console.log & front-end jobs
console.log & front-end jobs bind & function let log = console.log; let obj = {}; log(obj); ...
- C++算法代码——[TYVJ]单数?双数?
题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=1178 题目描述 Bessie那惨无人道的二年级老师搞了一个有 N (1 < ...
- css故障文字动画
免费分享95套java实战项目,不仅有源码还有对应的开发视频,关注公众号『勾玉技术』回复"95"即可获取 首先给内容上hover和before, .glitch:hover:bef ...
- IVMS-5000海康平台安装
某学校系统因中勒索病毒重装监控系统平台 一 安装前准备 二 数据库安装 采用免安装版本安装,原先平台采用免安装版mysql 5.6.24 ,学校IT管理员将数据库文件完全复制,用虚拟机将数据库搭 ...
- 【开源】.net微服务开发引擎Anno 让复杂的事简单点- 日志、链路追踪一目了然 (上)
1.Anno简介? Anno是一个微服务框架引擎.入门简单.安全.稳定.高可用.全平台可视化监控.依赖第三方框架少.详情请查看<[开源].net微服务开发引擎Anno开源啦> 本章主题:. ...