c++多线程编程:常见面试题
题目:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码
子线程与主线程必有一个满足条件(flag == num),不满足条件的那个线程不可能获取unique_lock(会在wait中释放),只有满足条件的线程才能获取锁,执行程序
- mutex m;//保护条件的互斥访问
- condition_variable cond;//条件变量
- int flag = ;//条件
- void fun(int num) {
- for (int i = ; i<; 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 = ; j<num; j++)
- cout << j << " ";
- cout << endl;
- flag = (num == ) ? : ;
- cond.notify_one();//被阻塞的线程唤醒后lk.lock()恢复在调用wait前的状态
- }
- }
- int main() {
- thread child(fun, );
- fun();
- child.join();
- system("pause");
- return ;
- }
题目:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
- mutex m;
- condition_variable cond;
- int loop = ;
- int flag = ;
- void func(int id)
- {
- for (int i = ; i < loop; ++i)
- {
- unique_lock<mutex> lk(m);
- while (flag != id)
- cond.wait(lk);
- cout << static_cast<char>('A' + id) << " ";
- flag = (flag + ) % ;
- cond.notify_all();
- }
- }
- void main()
- {
- thread A(func, );
- thread B(func, );
- func();
- 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 = ;
- int flag;
- void func(int num)
- {
- for (int i = ; i < loop; ++i)
- {
- unique_lock<mutex> lk(m);
- while (num != flag)
- cond.wait(lk);
- cout << num + << " ";
- flag = (flag + ) % ;
- cond.notify_all();
- }
- }
- void main(int argc,char *argv[])
- {
- flag = atoi(argv[]);
- thread one(func, );
- thread two(func, );
- thread three(func, );
- func();
- 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 < || _writer > )
- _rcon.wait(lock);
- --_reader;
- ++_active;
- }
- void write_lock() {
- unique_lock<mutex> lock(_lock);
- ++_writer;
- while (_active != )
- _wcon.wait(lock);
- --_writer;
- _active = -;
- }
- void unlock() {
- unique_lock<mutex> lock(_lock);
- if (_active > ) {
- --_active;
- if (_active == ) _wcon.notify_one();
- }
- else {
- _active = ;
- if (_writer > ) _wcon.notify_one();
- else if (_reader > ) _rcon.notify_all();
- }
- }
- rwlock() :_writer(), _reader(), _active() {
- }
- };
- void t1(rwlock* rwl) {
- while () {
- cout << "I want to write." << endl;
- rwl->write_lock();
- cout << "writing..." << endl;
- this_thread::sleep_for(chrono::seconds());
- rwl->unlock();
- this_thread::sleep_for(chrono::seconds());
- }
- }
- void t2(rwlock* rwl) {
- while () {
- cout << "t2-I want to read." << endl;
- rwl->read_lock();
- cout << "t2-reading..." << endl;
- this_thread::sleep_for(chrono::seconds());
- rwl->unlock();
- }
- }
- void t3(rwlock* rwl) {
- while () {
- cout << "t3-I want to read." << endl;
- rwl->read_lock();
- cout << "t3-reading..." << endl;
- this_thread::sleep_for(chrono::seconds());
- 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 ;
- }
线程安全的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();
- void worker1(future<int> fut)
- {//线程1
- printf("this is thread1\n");
- flag = ;
- 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 = ;
- prom.set_value();//线程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() == );
///将本线程从调用线程中分离出来,允许本线程独立执行- one.detach();
- two.detach();
- //exit(1);//主线程到这里退出
- printf("main thread exit\n");
- system("pause");
- return ;
- }
http://blog.csdn.net/liuxuejiang158blog/article/details/22300081
c++多线程编程:常见面试题的更多相关文章
- 整理的最全 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基础系列16:一文读懂Java IO流和常见面试题
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- 【搞定 Java 并发面试】面试最常问的 Java 并发基础常见面试题总结!
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.欢迎 Sta ...
- 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...
- Java面试炼金系列 (1) | 关于String类的常见面试题剖析
Java面试炼金系列 (1) | 关于String类的常见面试题剖析 文章以及源代码已被收录到:https://github.com/mio4/Java-Gold 0x0 基础知识 1. '==' 运 ...
- Spring 常见面试题总结 | JavaGuide
首发于 JavaGuide 在线网站:Spring 常见面试题总结 最近在对 JavaGuide 的内容进行重构完善,同步一下最新更新,希望能够帮助你. Spring 基础 什么是 Spring 框架 ...
- java常见面试题及答案 1-10(基础篇)
java常见面试题及答案 1.什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"? Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程.Java 源文件被 ...
随机推荐
- Linux centos7开机界面出现多个选项
centos7开机界面出现多个选项时 前面几个选项正常启动,最后一个选项急救模式启动(系统出项问题不能正常启动时使用并修复系统) 在CentOS更新后,并不会自动删除旧内核.所以在启动选项中会有多个内 ...
- 技术抄录_Java高级架构师教程
1.B2C商城项目实战 2.高性能架构专题 3.架构筑基与开源框架解析专题 4.团队协作开发专题 5.微服务架构专题 6.设计模式 附上[架构资料] ...
- DELETE - 删除一个表中的行
SYNOPSIS DELETE FROM [ ONLY ] table [ WHERE condition ] DESCRIPTION 描述 DELETE 从指明的表里删除满足 WHERE 子句的行. ...
- 如何移除不再插入Windows设备的信息
Howto: Remove devices from Windows that are not connected to the system anymore 如何移除不再插入Windows设备的信息 ...
- ORA-03113: end-of-file on & ORA-07445
--------------ORA-03113: end-of-file on-------------- SQL> show parameter background_dump; NAME T ...
- BZOJ3940: [Usaco2015 Feb]Censoring (AC自动机)
题意:在文本串上删除一些字符串 每次优先删除从左边开始第一个满足的 删除后剩下的串连在一起重复删除步骤 直到不能删 题解:建fail 用栈存当前放进了那些字符 如果可以删 fail指针跳到前面去 好菜 ...
- git-忽略文件改动不进行提交
命令:git update-index --assume-unchanged 文件名 作用:忽略文件的改动,但是不加入.gitignore 文件中,这样可以达到仅在本地目录中忽略,不影响其他团队成员的 ...
- Informatica抽取SQL Server数据库乱码
1.首先确认数据库的关系连接所使用的代码页,是否一致 2.如果上述方法不行,在Designer中更改数据类型,将string类型改为nstring类型,中文就没有乱码了 3.SQL Server数据库 ...
- Linux启动流程CentOS6和7的区别
目 录 Linux启动流程 I 第1章 CentOS6启动流程 1 1.1 BIOS 1 1.2 MBR 1 1.3 GRUB 1 1.4 kernel(加载内核) ...
- php函数之数组
关联数组 isset bool isset( mixed $val [, mix $...]) 变量是否已设置并且非null.多个参数从左到右计算. 判断null $a=null;var_dump(i ...