一些c++多线程习题
题目1:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码
代码1:
- #include <iostream>
- #include <thread>
- #include <mutex>
- using namespace std;
- const int count = ;
- int flag = ;
- std::mutex mtex;
- void fun(const int num, const string &str) {
- for(int i = ; i < count; ++i) {
- while(num != flag) std::this_thread::yield();
- mtex.lock();
- for(int j = ; j < num; ++j) {
- cout << str << endl;
- }
- std::this_thread::sleep_for(std::chrono::seconds());
- flag = (flag == ? : );
- mtex.unlock();
- }
- }
- int main(void) {
- auto start = std::chrono::high_resolution_clock::now();
- thread child(fun, , "child");
- fun(, "father");
- child.join();
- auto end = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::milli> elapsed = end - start;
- cout << elapsed.count() << endl;
- return ;
- }
代码2:
- #include <iostream>
- #include <thread>
- #include <mutex>
- #include <condition_variable>
- using namespace std;
- const int count = ;
- int flag = ;
- condition_variable cv;
- std::mutex mtex;
- void fun(const int num, const string &str) {
- for(int i = ; i < count; ++i) {
- unique_lock<std::mutex> lk(mtex);
- cv.wait(lk, [&]{
- return num == flag;
- });
- for(int j = ; j < num; ++j) {
- cout << str << endl;
- }
- std::this_thread::sleep_for(std::chrono::seconds());
- flag = (flag == ? : );
- mtex.unlock();
- cv.notify_one();
- }
- }
- int main(void) {
- auto start = std::chrono::high_resolution_clock::now();
- thread child(fun, , "child");
- fun(, "father");
- child.join();
- auto end = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::milli> elapsed = end - start;
- cout << elapsed.count() << endl;
- return ;
- }
题目2:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推
代码1:
- #include <iostream>
- #include <thread>
- #include <mutex>
- using namespace std;
- int main(void) {
- std::mutex mtex;
- int cnt = ;
- auto work = [&](char ch, int num) {
- while(num--) {
- while(ch != cnt + 'A') std::this_thread::yield();
- std::unique_lock<std::mutex> lk(mtex);
- cout << ch;
- cnt = (cnt + ) % ;
- lk.unlock();
- }
- };
- thread t1(work, 'A', );
- thread t2(work, 'B', );
- work('C', );
- t1.join();
- t2.join();
- return ;
- }
代码2:
- #include <iostream>
- #include <thread>
- #include <mutex>
- #include <chrono>
- #include <condition_variable>
- using namespace std;
- condition_variable cv;
- std::mutex mtex;
- int cnt = ;
- void work(char ch, int num) {
- while(num--) {
- std::this_thread::sleep_for(std::chrono::seconds());
- unique_lock<std::mutex> lk(mtex);
- cv.wait(lk, [&]{
- return 'A' + cnt == ch;
- });
- cout << ch;
- cnt = (cnt + ) % ;
- lk.unlock();
- cv.notify_one();
- }
- }
- int main(void) {
- thread t1(work, 'A', );
- thread t2(work, 'B', );
- work('C', );
- t1.join();
- t2.join();
- return ;
- }
题目3:(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....
代码:
- #include <iostream>
- #include <thread>
- #include <mutex>
- #include <fstream>
- #include <condition_variable>
- using namespace std;
- const string filename = "D://code//c++//ac36";
- condition_variable cv;
- std::mutex mtex;
- int vis[] = {, , , };//四个文件上一次分别写入的值
- ofstream f1(filename + "_A.txt");
- ofstream f2(filename + "_B.txt");
- ofstream f3(filename + "_C.txt");
- ofstream f4(filename + "_D.txt");
- ofstream *file[];
- void solve(const int x, int gg) {
- while(gg--){
- for(int i = ; i < ; ++i) {
- std::unique_lock<std::mutex> lk(mtex);
- if(x == ) {
- cv.wait(lk, [&]{
- return vis[i] == ;
- });
- (*file[i]) << ;
- vis[i] = ;
- lk.unlock();
- cv.notify_all();
- }else if(x == ) {
- cv.wait(lk, [&]{
- return vis[i] == ;
- });
- (*file[i]) << ;
- vis[i] = ;
- lk.unlock();
- cv.notify_all();
- }else if(x == ) {
- cv.wait(lk, [&]{
- return vis[i] == ;
- });
- (*file[i]) << ;
- vis[i] = ;
- lk.unlock();
- cv.notify_all();
- }else {
- cv.wait(lk, [&]{
- return vis[i] == ;
- });
- (*file[i]) << ;
- vis[i] = ;
- lk.unlock();
- cv.notify_all();
- }
- }
- }
- }
- int main(void) {
- file[] = &f1;
- file[] = &f2;
- file[] = &f3;
- file[] = &f4;
- thread t1(solve, , );
- thread t2(solve, , );
- thread t3(solve, , );
- solve(, );
- t1.join();
- t2.join();
- t3.join();
- for(int i = ; i < ; ++i) {
- file[i]->close();
- }
- return ;
- }
题目4:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者读时写者也不能写
代码:
- #include <iostream>
- #include <thread>
- #include <mutex>
- #include <fstream>
- #include <stdio.h>
- #include <condition_variable>
- using namespace std;
- const string filename = "D://code//c++//ac36.txt";
- std::condition_variable cv;
- std::mutex mtx;
- int cnt = ;
- ifstream in(filename);
- ofstream out(filename, ios::app);
- void write() {
- char ch;
- while(true) {
- std::unique_lock<std::mutex> lk(mtx);
- ch = getchar();
- out << ch;
- ++cnt;
- lk.unlock();
- cv.notify_all();
- }
- }
- void read() {
- char ch;
- while(true) {
- std::unique_lock<std::mutex> lk(mtx);
- cv.wait(lk, [&]{
- return cnt > ;
- });
- in >> ch;
- cout << "cout: " << ch << endl;
- --cnt;
- }
- }
- int main(void) {
- cnt = in.tellg();
- std::thread tw(write);
- std::thread tr1(read);
- std::thread tr2(read);
- std::thread tr3(read);
- tw.join();
- tr1.join();
- tr2.join();
- tr3.join();
- in.close();
- out.close();
- return ;
- }
题目5:
线程安全的 queue
STL 中的 queue 是非线程安全的,一个组合操作:front(); pop() 先读取队首元素然后删除队首元素,若是有多个线程执行这个组合操作的话,可能会发生执行序列交替执行,导致一些意想不到的行为。因此需要重新设计线程安全的 queue 的接口
代码:
- #include <iostream>
- #include <thread>
- #include <mutex>
- #include <queue>
- #include <chrono>
- #include <condition_variable>
- using namespace std;
- template <typename T>
- class thread_safe_queue{
- private:
- std::condition_variable cv;
- std::queue<T> que;
- std::mutex mtx;
- public:
- thread_safe_queue() = default;
- thread_safe_queue(const std::queue<T> q) : que(q) {}
- thread_safe_queue(const thread_safe_queue &tsf) {
- std::unique_lock<std::mutex> lk(mtx);
- que = tsf.que;
- }
- ~thread_safe_queue() = default;
- void push(const T &value) {
- std::unique_lock<std::mutex> lk(mtx);
- que.push(value);
- lk.unlock();
- cv.notify_all();
- }
- T pop(void) {
- std::unique_lock<std::mutex> lk(mtx);
- cv.wait(lk, [&]{
- return bool(!que.empty());
- });
- T value = que.front();
- que.pop();
- return value;
- }
- bool empty(void) {
- std::unique_lock<std::mutex> lk(mtx);
- return que.empty();
- }
- };
- thread_safe_queue<int> q;
- std::mutex mtx;
- int main(void) {
- auto push_value = [&]{
- for(int i = ; i < ; ++i) {
- q.push(i);
- std::this_thread::sleep_for(std::chrono::seconds());
- }
- };
- auto pop_value = [&]{
- while() {
- while(!q.empty()) {
- std::unique_lock<std::mutex> lk(mtx);
- cout << q.pop() << '\n';
- }
- }
- };
- thread push_thread1(push_value);
- thread pop_thread1(pop_value);
- thread pop_thread2(pop_value);
- thread pop_thread3(pop_value);
- push_thread1.join();
- pop_thread1.join();
- pop_thread2.join();
- pop_thread3.join();
- return ;
- }
题目6:编写程序完成如下功能:
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的时候退出
代码1:
- #include <iostream>
- #include <thread>
- #include <mutex>
- #include <condition_variable>
- using namespace std;
- std::condition_variable cv;
- std::mutex metx;
- int g_Flag = ;
- int cnt = ;
- bool flag = false;
- int main(void) {
- thread t1([&]{
- std::unique_lock<std::mutex> lk(metx);
- cout << "this is thread1\n";
- g_Flag = ;
- ++cnt;
- cv.wait(lk, [&]{{
- return flag;
- }});
- cout << "thread1 exit\n";
- });
- thread t2([&]{
- std::unique_lock<std::mutex> lk(metx);
- cout << "this is thread2\n";
- g_Flag = ;
- cnt++;
- flag = true;
- cv.notify_all();
- cout << "thread2 exit\n";
- });
- t1.detach();//分离线程
- t2.detach();
- std::unique_lock<std::mutex> lc(metx);
- cv.wait(lc, [&]{
- return cnt >= ;
- });
- cout << "main thread exit\n";
- return ;
- }
代码2:
- #include <iostream>
- #include <thread>
- #include <mutex>
- #include <atomic>
- #include <future>
- using namespace std;
- atomic<int> g_Flag(), cnt();
- void thread1(std::future<int> fu) {
- cout << "this is thread1\n";
- g_Flag = ;
- ++cnt;
- fu.get();//线程1阻塞至线程2设置共享状态, get等待异步操作结束并返回结果
- cout << "thread1 exit\n";
- }
- void thread2(std::promise<int> pro) {
- cout << "this is thread2\n";
- g_Flag = ;
- ++cnt;
- cout << "thread2 exit\n";
- pro.set_value();//设置共享值
- }
- int main(void) {
- std::promise<int> prom;//创建一个promise对象
- std::future<int> fu = prom.get_future();//获得promise内部的future,fut将和prom共享prom中的共享状态
- std::thread t1(thread1, std::move(fu));//通过fut在线程1中得到线程2的状态
- std::thread t2(thread2, std::move(prom));//通过prom设置线程2中的共享状态
- t1.detach();
- t2.detach();
- while(cnt < );
- cout << "main thread exit\n";
- return ;
- }
一些c++多线程习题的更多相关文章
- Java多线程习题 ===重点 ,错题积累
多线程重点,错题分析 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: . 12: 13: 14: 15:
- Java并发相关知识点梳理和研究
1. 知识点思维导图 (图比较大,可以右键在新窗口打开) 2. 经典的wait()/notify()/notifyAll()实现生产者/消费者编程范式深入分析 & synchronized 注 ...
- 算法(第四版)C# 习题题解——2.3
写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 查找更为方便的版本见:http ...
- Java多线程之内存可见性和原子性:Synchronized和Volatile的比较
Java多线程之内存可见性和原子性:Synchronized和Volatile的比较 [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article ...
- Java精通并发-多线程同步关系实例剖析与详解
在上一次https://www.cnblogs.com/webor2006/p/11422587.html中通过实践来解了一个案例,先来回顾一下习题: 编写一个多线程程序,实现这样的一个目标: 1.存 ...
- Java习题练习
Java习题练习 1. 依赖注入和控制反转是同一概念: 依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同.依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应 ...
- Java习题10.25
Java习题10.25 1. 实际上这道题考查的是两同两小一大原则: 方法名相同,参数类型相同 子类返回类型小于等于父类方法返回类型, 子类抛出异常小于等于父类方法抛出异常, 子类访问权限大于等于父类 ...
- Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
随机推荐
- requirejs——基础
一.requirejs存在的意义: 我们引用外部JS文件通常是这样引用的: <script src="1.js"></script> <script ...
- DataReader方式 获取数据
/// /// 得到一个对象实体 DataReader方式 /// /// /// 成功返回对象模型,失败返回null public DotNet.Model.Base_Department GetM ...
- chart左侧
左侧单位 Chart1.Axes.Left.Minimum := ; Chart1.Axes.Left.Maximum := Series1.YValues.MaxValue * ; Chart1.A ...
- WebRTC相关的基础知识点
这里主要用来记录自己整理的和webRTC相关的一些基本的知识点,后续整理的一些基础和零碎的知识点都会更新在这里.内容大部分来自于webRTC官网.w3c以及一些前辈们的博客中的文章和相关书籍等. 20 ...
- java之飞机大战的记分标准
import java.awt.Image; import java.util.ArrayList; import java.util.Timer; import javax.swing.ImageI ...
- 【转发】徐汉彬:Web系统大规模并发——电商秒杀与抢购
徐汉彬:Web系统大规模并发——电商秒杀与抢购 发表于2014-12-02 09:30| 73110次阅读| 来源CSDN| 114 条评论| 作者徐汉彬 问底徐汉彬大数据 摘要:电商的秒杀和抢购,从 ...
- python子进程模块subprocess详解与应用实例 之一
subprocess--子进程管理器 一.subprocess 模块简介 subprocess最早是在2.4版本中引入的. subprocess模块用来生成子进程,并可以通过管道连接它们的输入/输出/ ...
- 简单tarjan》一道裸题(BZOJ1051)(easy)
这是一道水题,实际考察的是你会不会写强连通分量...(在BZOJ上又水了一道题) Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B ...
- Tensorflow训练结果测试
代码参考(https://blog.csdn.net/disiwei1012/article/details/79928679) import osimport sysimport randomimp ...
- 217. Contains Duplicate数组重复元素 123
[抄题]: Given an array of integers, find if the array contains any duplicates. Your function should re ...