题目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++多线程习题的更多相关文章

  1. Java多线程习题 ===重点 ,错题积累

    多线程重点,错题分析 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: . 12: 13: 14: 15:

  2. Java并发相关知识点梳理和研究

    1. 知识点思维导图 (图比较大,可以右键在新窗口打开) 2. 经典的wait()/notify()/notifyAll()实现生产者/消费者编程范式深入分析 & synchronized 注 ...

  3. 算法(第四版)C# 习题题解——2.3

    写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 查找更为方便的版本见:http ...

  4. Java多线程之内存可见性和原子性:Synchronized和Volatile的比较

    Java多线程之内存可见性和原子性:Synchronized和Volatile的比较     [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article ...

  5. Java精通并发-多线程同步关系实例剖析与详解

    在上一次https://www.cnblogs.com/webor2006/p/11422587.html中通过实践来解了一个案例,先来回顾一下习题: 编写一个多线程程序,实现这样的一个目标: 1.存 ...

  6. Java习题练习

    Java习题练习 1. 依赖注入和控制反转是同一概念: 依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同.依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应 ...

  7. Java习题10.25

    Java习题10.25 1. 实际上这道题考查的是两同两小一大原则: 方法名相同,参数类型相同 子类返回类型小于等于父类方法返回类型, 子类抛出异常小于等于父类方法抛出异常, 子类访问权限大于等于父类 ...

  8. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

  9. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

随机推荐

  1. centos 系统使用verdaccio搭建npm私库

    .安装nodejs yum install -y nodejs 2.安装verdaccio npm install -g verdaccio --unsafe-perm 3.配置 a.修改配置文件 c ...

  2. IDA Pro 权威指南学习笔记(一) - 启动 IDA

    启动 IDA 启动 IDA,有一个欢迎界面 之后有一个对话框 选择 New 将启动一个对话框来选择将要分析的文件 选择 Go 将使 IDA 打开一个空白的工作区 如果要选择分析的文件,可以直接拖到 I ...

  3. python学习——练习题(1)

    """ 题目:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? """ import itertools d ...

  4. Java微信公众平台开发(九)--关键字回复以及客服接口实现(该公众号暂时无法提供服务解决方案)

    转自:http://www.cuiyongzhi.com/post/47.html 我们在微信公众号的后台可以发现微信给我们制定了两种模式,一种是开发者模式(也就是我们一直在做的开发),还有一种模式是 ...

  5. Eclipse 代码风格配置

    代码风格配置:

  6. pandas中DataFrame相关

    1.创建 1.1  标准格式创建 DataFrame创建方法有很多,常用基本格式是:DataFrame 构造器参数:DataFrame(data=[],index=[],coloumns=[]) In ...

  7. css字体属性(font)

    字体名称属性(font-family) 这个属性设定字体名称,如Arial, Tahoma, Courier等.例句如下: .s1 {font-family:Arial}     字体大小属性(fon ...

  8. 当一个SQL语句同时出现了where,group by,having,order by的时候,执行顺序和编写顺序

    当一个查询语句同时出现了where,group by,having,order by的时候,执行顺序和编写顺序 1.执行where xx对全表数据做筛选,返回第1个结果集. 2.针对第1个结果集使用g ...

  9. php opcode

    opcode是计算机指令中的一部分,用于指定要执行的操作, 指令的格式和规范由处理器的指令规范指定. 除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显式的操作数. 这些操作数可能是寄存 ...

  10. 关于windows的锁定状态

    本来以为要在项目里用上的,现在看来不需要了,把相关的函数列一下吧,以后如果用到了,再写详细点 锁定计算机 : LockWorkStation 注册Windows状态变化的监听函数: BOOL WTSR ...