题目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. 【树莓派】开机自启动脚本方法之一(.Desktop文件)

    转载处: 又一个让树莓派开机运行Python脚本的方法 Linux 创建启动器(.Desktop文件) 首先,树莓派使用的是官方推荐的镜像:RASPBIAN: 在树莓派上常常会需要开机自启动pytho ...

  2. Java微信公众平台开发(十二)--微信用户信息的获取

    转自:http://www.cuiyongzhi.com/post/56.html 前面的文章有讲到微信的一系列开发文章,包括token获取.菜单创建等,在这一篇将讲述在微信公众平台开发中如何获取微信 ...

  3. cacti启动有图无数据

    cactiEZ服务器重启后,获取不到图形的解决办法 cd /var/www/html/cli/ php -q rebuild_poller_cache.php -d myisamchk --safe- ...

  4. Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart)

    在接触WebService时值得收藏的一篇文章: 在调试Axis1.4访问WebService服务时,出现以下错误: Unable to find required classes (javax.ac ...

  5. 1&nbsp;任务管理&nbsp;&nbsp;--转载于电子工程世界

    uC/OS-II 中最多可以支持64 个任务,分别对应优先级0-63,其中0 为最高优先级.63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个. uC ...

  6. 在java中RandomAccessFile类的作用:对指定文件可以进行读写的操作

  7. 深入剖析SolrCloud(三)

    作者:洞庭散人 出处:http://phinecos.cnblogs.com/ 本博客遵从Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由 ...

  8. solr4.3+tomcat入门部署

    solr4.3的入门配置   目前阿帕奇官方仅推荐2个比较稳定的版本一个是4.3的版本,一个3.6的版本     3.6的版本没有用过,所以在此无涉及,下面就来说说solr4.3的入门配置     s ...

  9. 【bzoj1614】[Usaco2007 Jan]Telephone Lines架设电话线

    题目描述 Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务.于是,FJ必须为此向电信公司支付一定的费用.     FJ的农场周围分布着N(1 <= N < ...

  10. 面试题:servlet jsp cook session 背1

    一.Servlet是什么?JSP是什么?它们的联系与区别是什么? Servlet是Java编写的运行在Servlet容器的服务端程序,狭义的Servlet是指Servlet接口,广义的Servlet是 ...