题目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. IT_Qestion

    1. Javascript 回调 Promise 2. Angularjs $parent 3. CSS margin padding border 4. Angularjs $filter 5. D ...

  2. php浏览器端调试输出方法

     1.利用js打印到浏览器控制台 <?php function console_log($data) {     if (is_array($data) || is_object($data)) ...

  3. Python中正则表达式对中文的匹配问题

    python匹配中文的时候特别要注意的是匹配的正则字符串是否是Unicode格式的: import re source = "s2f程序员杂志一2d3程序员杂志二2d3程序员杂志三2d3程序 ...

  4. Hadoop IO 特性详解(1)

    本文结合hadoop : the definitive guide精心而作,包含作者的心血,希望可以帮助大家理解一点hdfs的皮毛,足矣.(charles@xingbod.cn) hadoop本身自带 ...

  5. pandas中DataFrame相关

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

  6. java Web jsp四大作用域和九大内置对象

    JSP中的四大作用域:page.request.session.application 这四大作用域,其实就是其九大内置对象中的四个,为什么说他们也是JSP的四大作用域呢?因为这四个对象都能存储数据, ...

  7. 六.使用list和tuple

    list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可以用一个list表示: classmates = ...

  8. 2-python代码坑点

    #切片: # L = ['aaa', 'bbb', 'ccc', 'ddd'] # print(L[1 : 3]) #取[1, 3):下标 # L = list(range(100)) # print ...

  9. 7.python实现高效端口扫描器之nmap模块

    对于端口扫描,使用的最多的就是nmap这个工具,不想python已经强大到,提供了nmap这个扫描端口的模块. 本片文章主要介绍nmap模块的两个常用类: PortScanner()类,实现一个nma ...

  10. css总结20:TCP通信协议WebSocket

    HTML5 WebSocket 1 介绍: WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. 在WebSocket API中,浏览器和服务器只需要做一个握手的动 ...