一些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源码解析 前面 ...
随机推荐
- MongDB安装使用
4.MongoDB 下载 MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包,你可以从MongoDB官网下载安装,MongoDB 预编译二进制包下载地址:https://www.m ...
- STM32用有源蜂鸣器实现闹钟的声响
有源蜂鸣器的声音是固定的,工作电压恒定,改变通断电的时间获得不同时长的音响,譬如连续音.快速短音.慢速长音(类似莫尔斯电报)来区分不同的报警信息. 简单的说,有源蜂鸣器只能发出一种声音,因为它的频率是 ...
- HDFS的介绍
设计思想 分而治之:将大文件.大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析: 在大数据系统中作用:为各类分布式运算框架(如:mapreduce,spark,te ...
- JAVA的对称加密算法AES——加密和解密
出自: http://blog.csdn.net/hongtashan11/article/details/6599645 http://www.cnblogs.com/liunanjava/p/42 ...
- schedule和scheduleAtFixedRate的区别
- SpringSecurity3.X权限原理(转)
这里给出一个简单的安全验证的实现例子,先说一下需求: 1.通过登录页面进行登录 2.用户登录前访问被保护的地址时自动跳转到登录页面 3.用户信息存储在数据表中 4.用户权限信息存在在数据表中 5. ...
- 【光速使用开源框架系列】图片加载框架ImageLoader
[关于本系列] 最近看了不少开源框架,网上的资料也非常多,但是我认为了解一个框架最好的方法就是实际使用.本系列博文就是带领大家快速的上手一些常用的开源框架,体会到其作用. 由于作者水平有限,本系列只会 ...
- 2014蓝桥杯B组初赛试题《奇怪的分式》
题目描述: 上小学的时候,小明经常自己发明新算法.一次,老师出的题目是: 1/4 乘以 8/5 小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png) ...
- 690. Employee Importance员工权限重要性
[抄题]: You are given a data structure of employee information, which includes the employee's unique i ...
- sfidsk创建可启动分区问题
前言 由于工作上需要经常要为嵌入式设备制作启动SD卡,因此本人使用sfdisk编写了自动分区.格式化和安装文件的脚本.(不选择fdisk是因为它是为用户交互设计的,在脚本上使用不够方便) 实际使用过程 ...