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 ...
随机推荐
- Hadoop 3.0 EC技术
Hadoop 3.0 EC技术 EC的设计目标 Hadoop默认的3副本方案需要额外的200%的存储空间.和网络IO开销 而一些较低I/O的warn和cold数据,副本数据的访问是比较少的(hot数据 ...
- CSS3实现 垂直居中 水平居中 的技巧
1 1 1 How To Center Anything With CSS Front End posted by Code My Views 1 Recently, we took a dive i ...
- LeetCode & tree & binary tree
LeetCode & tree & binary tree 树 & 二叉树 refs https://leetcode.com/problemset/all/?topicSlu ...
- Web 前端必备的各种跨域方式汇总
Web 前端必备的各种跨域方式汇总 跨域方式汇总 同源策略 协议相同 + 域名相同 + 端口相同 https://www.xgqfrms.xyz/index.html https://www.xgqf ...
- CSS Dark Mode
CSS Dark Mode https://kevq.uk/automatic-dark-mode/ https://kevq.uk/how-to-add-css-dark-mode-to-a-web ...
- nasm astrchr函数 x86
xxx.asm: %define p1 ebp+8 %define p2 ebp+12 %define p3 ebp+16 section .text global dllmain export as ...
- C++算法代码——统计数字
题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=1109 题目描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000( ...
- Mybatis注解开发之@CacheNamespace:实现注解二级缓存的使用
MyBatis二级缓存使用: 官方建议在service使用缓存,但是你也可以直接在mapper层缓存,这里的二级缓存就是直接在Mapper层进行缓存操作 Mybatis的二级缓存实现也十分简单,只要在 ...
- Bitter.NotifyOpenPaltform : HTTP 异步消息接收调度中心--开源贡献 之 一:简介
现在互联网的系统越来越趋向于复杂,从单体系统到现在的微服务体系演变.公司与公司的分工也越来越明确. 大数据公司提供了大数据服务 人脸识别公司提供了人脸识别服务 OCR 公司提供了专业的OCR 服务 车 ...
- 基于西门子S7-1500的大型焊接机全套程序,使用博图V14打开(带全部注释)
程序说明:本套程序是在从事自动化行业时候的做的项目的程序,经过在设备上运行测试,其中包含20多个轴的伺服控制以及模拟量,数字量IO的控制,包括扫描枪的读取,属于大型程序,总步数有好几万步. 本程序注释 ...