c++多线程编程:常见面试题
题目:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码
子线程与主线程必有一个满足条件(flag == num),不满足条件的那个线程不可能获取unique_lock(会在wait中释放),只有满足条件的线程才能获取锁,执行程序
mutex m;//保护条件的互斥访问 condition_variable cond;//条件变量 int flag = 10;//条件 void fun(int num) {for (int i = 0; i<50; i++) {unique_lock<mutex> lk(m);//A unique lock is an object that manages a mutex object with unique ownership in both states: locked and unlocked. while (flag != num)cond.wait(lk);//在调用wait时会执行lk.unlock() for (int j = 0; j<num; j++)cout << j << " ";cout << endl;flag = (num == 10) ? 100 : 10;cond.notify_one();//被阻塞的线程唤醒后lk.lock()恢复在调用wait前的状态 } } int main() {thread child(fun, 10);fun(100);child.join();system("pause");return 0; }
题目:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
mutex m; condition_variable cond; int loop = 10; int flag = 0;void func(int id) {for (int i = 0; i < loop; ++i){unique_lock<mutex> lk(m);while (flag != id)cond.wait(lk);cout << static_cast<char>('A' + id) << " ";flag = (flag + 1) % 3;cond.notify_all();} }void main() {thread A(func, 0);thread B(func, 1);func(2);cout << endl;A.join();B.join();system("pause"); }
题目(google笔试题):有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:
A:1 2 3 4 1 2....
B:2 3 4 1 2 3....
C:3 4 1 2 3 4....
D:4 1 2 3 4 1....
mutex m; condition_variable cond; int loop = 10; int flag;void func(int num) {for (int i = 0; i < loop; ++i){unique_lock<mutex> lk(m);while (num != flag)cond.wait(lk);cout << num + 1 << " ";flag = (flag + 1) % 4;cond.notify_all();} }void main(int argc,char *argv[]) {flag = atoi(argv[1]);thread one(func, 1);thread two(func, 2);thread three(func, 3);func(0);one.join();two.join();three.join();cout << endl;system("pause"); }
读者写者问题
这也是一个非常经典的多线程题目,题目大意如下:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者读时写者也不能写。
class rwlock { private:mutex _lock;condition_variable _wcon, _rcon;unsigned _writer, _reader;int _active; public:void read_lock() {unique_lock<mutex> lock(_lock);++_reader;while (_active < 0 || _writer > 0)_rcon.wait(lock);--_reader;++_active;}void write_lock() {unique_lock<mutex> lock(_lock);++_writer;while (_active != 0)_wcon.wait(lock);--_writer;_active = -1;}void unlock() {unique_lock<mutex> lock(_lock);if (_active > 0) {--_active;if (_active == 0) _wcon.notify_one();}else {_active = 0;if (_writer > 0) _wcon.notify_one();else if (_reader > 0) _rcon.notify_all();}}rwlock() :_writer(0), _reader(0), _active(0) {} };void t1(rwlock* rwl) {while (1) {cout << "I want to write." << endl;rwl->write_lock();cout << "writing..." << endl;this_thread::sleep_for(chrono::seconds(5));rwl->unlock();this_thread::sleep_for(chrono::seconds(5));} }void t2(rwlock* rwl) {while (1) {cout << "t2-I want to read." << endl;rwl->read_lock();cout << "t2-reading..." << endl;this_thread::sleep_for(chrono::seconds(1));rwl->unlock();} }void t3(rwlock* rwl) {while (1) {cout << "t3-I want to read." << endl;rwl->read_lock();cout << "t3-reading..." << endl;this_thread::sleep_for(chrono::seconds(1));rwl->unlock();} }int main() {rwlock* rwl = new rwlock();thread th1(t1, rwl);thread th2(t2, rwl);thread th3(t3, rwl);th1.join();th2.join();th3.join();system("pause");return 0; }
线程安全的queue
STL中的queue是非线程安全的,一个组合操作:front(); pop()先读取队首元素然后删除队首元素,若是有多个线程执行这个组合操作的话,可能会发生执行序列交替执行,导致一些意想不到的行为。因此需要重新设计线程安全的queue的接口。
template<typename T> class threadsafe_queue { private:mutable std::mutex mut;std::queue<T> data_queue;std::condition_variable data_cond; public:threadsafe_queue() {}threadsafe_queue(threadsafe_queue const& other){std::lock_guard<std::mutex> lk(other.mut);data_queue = other.data_queue;}void push(T new_value)//入队操作 {std::lock_guard<std::mutex> lk(mut);data_queue.push(new_value);data_cond.notify_one();}void wait_and_pop(T& value)//直到有元素可以删除为止 {std::unique_lock<std::mutex> lk(mut);data_cond.wait(lk, [this] {return !data_queue.empty(); });value = data_queue.front();data_queue.pop();}std::shared_ptr<T> wait_and_pop(){std::unique_lock<std::mutex> lk(mut);data_cond.wait(lk, [this] {return !data_queue.empty(); });std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));data_queue.pop();return res;}bool try_pop(T& value)//不管有没有队首元素直接返回 {std::lock_guard<std::mutex> lk(mut);if (data_queue.empty())return false;value = data_queue.front();data_queue.pop();return true;}std::shared_ptr<T> try_pop(){std::lock_guard<std::mutex> lk(mut);if (data_queue.empty())return std::shared_ptr<T>();std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));data_queue.pop();return res;}bool empty() const{std::lock_guard<std::mutex> lk(mut);return data_queue.empty();} };
题目:编写程序完成如下功能:
1)有一int型全局变量g_Flag初始值为0
2) 在主线称中起动线程1,打印“this is thread1”,并将g_Flag设置为1
3) 在主线称中启动线程2,打印“this is thread2”,并将g_Flag设置为2
4) 线程序1需要在线程2退出后才能退出
5) 主线程在检测到g_Flag从1变为2,或者从2变为1的时候退出
atomic<int> flag(0);void worker1(future<int> fut) {//线程1 printf("this is thread1\n");flag = 1;fut.get();//线程1阻塞至线程2设置共享状态 get等待异步操作结束并返回结果printf("thread1 exit\n"); }void worker2(promise<int> prom) {//线程2 printf("this is thread2\n");//C++11的线程输出cout没有boost的好,还是会出现乱序,所以采用printf,有点不爽 flag = 2;prom.set_value(10);//线程2设置了共享状态后,线程1才会被唤醒 printf("thread2 exit\n"); }//利用promise future来控制线程退出的次序 int main() {promise<int> prom;future<int> fut = prom.get_future();thread one(worker1, move(fut));//注意future和promise不允许拷贝,但是具备move语义 thread two(worker2, move(prom));while (flag.load() == 0); ///将本线程从调用线程中分离出来,允许本线程独立执行one.detach();two.detach();//exit(1);//主线程到这里退出 printf("main thread exit\n");system("pause");return 0; }
http://blog.csdn.net/liuxuejiang158blog/article/details/22300081
转载于:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/5950400.html
c++多线程编程:常见面试题相关推荐
- 总结并发编程常见面试题
Hello,你好呀,我是大白(●-●) 目录标题 并发编程常见面试题 并发编程常见面试题 在Java中守护线程和用户线程的区别? 线程与进程的区别 什么是多线程中的上下文切换 死锁与活锁的区别,死锁与 ...
- Java并发编程—常见面试题
建议: 学习java并发前需要先掌握JVM知识 关于下面问题档案的详细解析都在后面推荐的相关系列文章中 一.线程安全相关 1.什么叫线程安全? 线程安全就是说多线程访问同一代码,不会产生不确定的结果. ...
- Linux网络编程常见面试题
概述 TCP和UDP是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流,TCP套接口是字节流套接口(str ...
- 并发编程常见面试题Synchronized 相 关 问 题
Synchronized 相 关 问 题 问 题 一 : Synchronized 用 过 吗 , 其 原 理 是 什 么? 这 是 一 道 Java 面 试 中 几 乎 百 分 百 会 问 到 的 ...
- Java多线程常见面试题及答案汇总1000道(春招+秋招+社招)
Java多线程面试题以及答案整理[最新版]Java多线程高级面试题大全(2021版),发现网上很多Java多线程面试题都没有答案,所以花了很长时间搜集,本套Java多线程面试题大全,汇总了大量经典的J ...
- java多线程常用面试_java的多线程常见面试题
并行和并发有什么区别? (推荐学习:java常见面试题) 并行是指两个或者多个事件在同一时刻发生:而并发是指两个或多个事件在同一时间间隔发生. 并行是在不同实体上的多个事件,并发是在同一实体上的多个事 ...
- iOS 多线程 自动释放池常见面试题代码
同步:代码依次执行,一个人执行多个任务,也是依次执行.一个人在同一时间只执行一个任务 异步:可以同时执行多个任务 进程:指在系统中运行的应用程序,每个进程都是独立的,都有独立的且安全的运行空间 线程: ...
- MySQL数据库常见面试题总结
1.数据库的常用范式: 第一范式(1NF):指表的列不可再分,数据库中表的每一列都是不可分割的基本数据项,同一列中不能有多个值: 第二范式(2NF):在 1NF 的基础上,还包含两部分的内容:一是表必 ...
- 加上项目路径 spring security忽略不生效_Spring 常见面试题「收藏」
Spring 常见面试题 1 Spring框架是什么?它的主要模块有哪些? Spring框架是一个Java平台,提供全面的基础设施支持开发Java应用程序.Spring处理基础设施部分,这样你就可以专 ...
- 总结Java常见面试题和答案
转载自 总结Java常见面试题和答案 int和Integer有什么区别? 答:int是java的原始数据类型,Integer是java为int提供的封装类,java为每个原始数据类型都提供了封装 ...
最新文章
- python matplotlib绘图 axes和pyplot用法的区别是什么?子图subplot
- confluence添加用户_玩转Confluence插件开发插件模块配置文件介绍(04)
- sicily 1012. Stacking Cylinders
- android 弹起键盘把ui顶上去的解决办法
- TikZ绘图示例——尺规作图: 圆内接正九边形的近似画法
- 2017-2018-2 20155315《网络对抗技术》Exp3:免杀原理与实践
- ceph搭建_如何一键搭建并管理Filecoin集群节点 | Gamma OS新功能上线
- 雅可比迭代法和高斯赛德尔迭代法
- Journal of BitcoinJ 从clone开始
- 九宫格日记 2017年12月19日(周二)
- 3D打印机之Marlin固件配置
- android图案解锁忘了怎么解,安卓手机解锁图案忘了怎么办?手机解锁密码忘了怎么办?...
- c语言合数的分解编程,C语言 · 分解质因数
- 图书行业的两个术语:实洋、码洋
- windows server 2008共享文件夹
- html网页制作比赛要求,校园网页设计大赛活动方案
- idb 怎么回复mysql_MySql数据库通过idb和frm恢复
- 关于先有鸡还是先有蛋,终于有正确答案了 1
- ...的Comparator和Compa
- 万丈高楼平地起 ——浅谈网格计算基础