• 一些c++多线程习题


    题目1:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码

    代码1:

     1 #include <iostream>
     2 #include <thread>
     3 #include <mutex>
     4 using namespace std;
     5 
     6 const int count = 50;
     7 int flag = 10;
     8 std::mutex mtex;
     9 
    10 void fun(const int num, const string &str) {
    11     for(int i = 0; i < count; ++i) {
    12         while(num != flag) std::this_thread::yield();
    13         mtex.lock();
    14         for(int j = 0; j < num; ++j) {
    15             cout << str << endl;
    16         }
    17         std::this_thread::sleep_for(std::chrono::seconds(1));
    18         flag = (flag == 10 ? 100 : 10);
    19         mtex.unlock(); 
    20     }
    21 }
    22 
    23 int main(void) {
    24     auto start = std::chrono::high_resolution_clock::now();
    25     thread child(fun, 10, "child");
    26     fun(100, "father");
    27     child.join();
    28     auto end = std::chrono::high_resolution_clock::now();
    29     std::chrono::duration<double, std::milli> elapsed = end - start;
    30     cout << elapsed.count() << endl;
    31 
    32     return 0;
    33 }
    View Code

    代码2:

     1 #include <iostream>
     2 #include <thread>
     3 #include <mutex>
     4 #include <condition_variable>
     5 using namespace std;
     6 
     7 const int count = 50;
     8 int flag = 10;
     9 condition_variable cv;
    10 std::mutex mtex;
    11 
    12 void fun(const int num, const string &str) {
    13     for(int i = 0; i < count; ++i) {
    14         unique_lock<std::mutex> lk(mtex);
    15         cv.wait(lk, [&]{
    16             return num == flag;
    17         });
    18         for(int j = 0; j < num; ++j) {
    19             cout << str << endl;
    20         }
    21         std::this_thread::sleep_for(std::chrono::seconds(1));
    22         flag = (flag == 10 ? 100 : 10);
    23         mtex.unlock();
    24         cv.notify_one();
    25     }
    26 }
    27 
    28 int main(void) {
    29     auto start = std::chrono::high_resolution_clock::now();
    30     thread child(fun, 10, "child");
    31     fun(100, "father");
    32     child.join();
    33     auto end = std::chrono::high_resolution_clock::now();
    34     std::chrono::duration<double, std::milli> elapsed = end - start;
    35     cout << elapsed.count() << endl;
    36 
    37     return 0;
    38 }
    View Code

    题目2:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推

    代码1:

     1 #include <iostream>
     2 #include <thread>
     3 #include <mutex>
     4 using namespace std;
     5 
     6 int main(void) {
     7     std::mutex mtex;
     8     int cnt = 0;
     9     auto work = [&](char ch, int num) {
    10         while(num--) {
    11             while(ch != cnt + 'A') std::this_thread::yield();
    12             std::unique_lock<std::mutex> lk(mtex);
    13             cout << ch;
    14             cnt = (cnt + 1) % 3;
    15             lk.unlock();
    16         }
    17     };
    18     thread t1(work, 'A', 10);
    19     thread t2(work, 'B', 10);
    20     work('C', 10);
    21 
    22     t1.join();
    23     t2.join();
    24 
    25     return 0;
    26 }
    View Code

    代码2:

     1 #include <iostream>
     2 #include <thread>
     3 #include <mutex>
     4 #include <chrono>
     5 #include <condition_variable>
     6 using namespace std;
     7 
     8 condition_variable cv;
     9 std::mutex mtex;
    10 int cnt = 0;
    11 
    12 void work(char ch, int num) {
    13     while(num--) {
    14         std::this_thread::sleep_for(std::chrono::seconds(1));
    15         unique_lock<std::mutex> lk(mtex);
    16         cv.wait(lk, [&]{
    17             return 'A' + cnt == ch;
    18         });
    19         cout << ch;
    20         cnt = (cnt + 1) % 3;
    21         lk.unlock();
    22         cv.notify_one();
    23     }
    24 }
    25 
    26 int main(void) {
    27     thread t1(work, 'A', 10);
    28     thread t2(work, 'B', 10);
    29     work('C', 10);
    30 
    31     t1.join();
    32     t2.join();
    33 
    34     return 0;
    35 }
    View Code

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

    代码:

     1 #include <iostream>
     2 #include <thread>
     3 #include <mutex>
     4 #include <fstream>
     5 #include <condition_variable>
     6 using namespace std;
     7 
     8 const string filename = "D://code//c++//ac36";
     9 condition_variable cv;
    10 std::mutex mtex;
    11 
    12 int vis[] = {4, 1, 2, 3};//四个文件上一次分别写入的值
    13 
    14 ofstream f1(filename + "_A.txt");
    15 ofstream f2(filename + "_B.txt");
    16 ofstream f3(filename + "_C.txt");
    17 ofstream f4(filename + "_D.txt");
    18 
    19 ofstream *file[4];
    20     
    21 void solve(const int x, int gg) {
    22     while(gg--){
    23         for(int i = 0; i < 4; ++i) {
    24 
    25             std::unique_lock<std::mutex> lk(mtex);
    26 
    27             if(x == 1) {
    28                 cv.wait(lk, [&]{
    29                     return vis[i] == 4;
    30                 });
    31                 (*file[i]) << 1;
    32                 vis[i] = 1;
    33                 lk.unlock();
    34                 cv.notify_all();
    35             }else if(x == 2) {
    36                 cv.wait(lk, [&]{
    37                     return vis[i] == 1;
    38                 });
    39                 (*file[i]) << 2;
    40                 vis[i] = 2;
    41                 lk.unlock();
    42                 cv.notify_all();
    43             }else if(x == 3) {
    44                 cv.wait(lk, [&]{
    45                     return vis[i] == 2;
    46                 });
    47                 (*file[i]) << 3; 
    48                 vis[i] = 3;
    49                 lk.unlock();
    50                 cv.notify_all();
    51             }else {
    52                 cv.wait(lk, [&]{
    53                     return vis[i] == 3;
    54                 });
    55                 (*file[i]) << 4;
    56                 vis[i] = 4;
    57                 lk.unlock();
    58                 cv.notify_all();
    59             }
    60         }
    61     }
    62 }
    63 
    64 int main(void) {
    65     file[0] = &f1;
    66     file[1] = &f2;
    67     file[2] = &f3;
    68     file[3] = &f4;
    69 
    70     thread t1(solve, 1, 10);
    71     thread t2(solve, 2, 10);
    72     thread t3(solve, 3, 10);
    73     solve(4, 10);
    74 
    75     t1.join();
    76     t2.join();
    77     t3.join();
    78 
    79     for(int i = 0; i < 4; ++i) {
    80         file[i]->close();
    81     }
    82     return 0;
    83 }
    View Code

    题目4:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者读时写者也不能写

    代码:

     1 #include <iostream>
     2 #include <thread>
     3 #include <mutex>
     4 #include <fstream>
     5 #include <stdio.h>
     6 #include <condition_variable>
     7 using namespace std;
     8 
     9 const string filename = "D://code//c++//ac36.txt";
    10 std::condition_variable cv;
    11 std::mutex mtx;
    12 int cnt = 0;
    13 
    14 ifstream in(filename);
    15 ofstream out(filename, ios::app);
    16 
    17 void write() {
    18     char ch;
    19     while(true) {
    20         std::unique_lock<std::mutex> lk(mtx);
    21         ch = getchar();
    22         out << ch;
    23         ++cnt;
    24         lk.unlock();
    25         cv.notify_all();
    26     }
    27 }
    28 
    29 void read() {
    30     char ch;
    31     while(true) {
    32         std::unique_lock<std::mutex> lk(mtx);
    33         cv.wait(lk, [&]{
    34             return cnt > 0;
    35         });
    36         in >> ch;
    37         cout << "cout: " << ch << endl;
    38         --cnt;
    39     }
    40 }
    41 
    42 int main(void) {
    43     cnt = in.tellg();
    44 
    45     std::thread tw(write);
    46     std::thread tr1(read);
    47     std::thread tr2(read);
    48     std::thread tr3(read);
    49 
    50     tw.join();
    51     tr1.join();
    52     tr2.join();
    53     tr3.join();
    54 
    55     in.close();
    56     out.close();
    57 
    58     return 0;
    59 }
    View Code

    题目5:

    线程安全的 queue

    STL 中的 queue 是非线程安全的,一个组合操作:front();  pop() 先读取队首元素然后删除队首元素,若是有多个线程执行这个组合操作的话,可能会发生执行序列交替执行,导致一些意想不到的行为。因此需要重新设计线程安全的 queue 的接口

    代码:

     1 #include <iostream>
     2 #include <thread>
     3 #include <mutex>
     4 #include <queue>
     5 #include <chrono>
     6 #include <condition_variable>
     7 using namespace std;
     8 
     9 template <typename T>
    10 class thread_safe_queue{
    11 private:
    12     std::condition_variable cv;
    13     std::queue<T> que;
    14     std::mutex mtx;
    15 
    16 public:
    17     thread_safe_queue() = default;
    18     thread_safe_queue(const std::queue<T> q) : que(q) {}
    19     thread_safe_queue(const thread_safe_queue &tsf) {
    20         std::unique_lock<std::mutex> lk(mtx);
    21         que = tsf.que;
    22     }
    23     ~thread_safe_queue() = default;
    24 
    25     void push(const T &value) {
    26         std::unique_lock<std::mutex> lk(mtx);
    27         que.push(value);
    28         lk.unlock();
    29         cv.notify_all();
    30     }
    31 
    32     T pop(void) {
    33         std::unique_lock<std::mutex> lk(mtx);
    34         cv.wait(lk, [&]{
    35             return bool(!que.empty());
    36         });
    37         T value = que.front();
    38         que.pop();
    39         return value;
    40     }
    41 
    42     bool empty(void) {
    43         std::unique_lock<std::mutex> lk(mtx);
    44         return que.empty();
    45     }
    46 };
    47 
    48 thread_safe_queue<int> q;
    49 std::mutex mtx;
    50 
    51 int main(void) {
    52 
    53     auto push_value = [&]{
    54         for(int i = 0; i < 100; ++i) {
    55             q.push(i);
    56             std::this_thread::sleep_for(std::chrono::seconds(1));
    57         }
    58     };
    59 
    60     auto pop_value = [&]{
    61         while(1) {
    62             while(!q.empty()) {
    63                 std::unique_lock<std::mutex> lk(mtx);
    64                 cout << q.pop() << '
    ';
    65             }
    66         }
    67     };
    68 
    69     thread push_thread1(push_value);
    70     thread pop_thread1(pop_value);
    71     thread pop_thread2(pop_value);
    72     thread pop_thread3(pop_value);
    73 
    74     push_thread1.join();
    75     pop_thread1.join();
    76     pop_thread2.join();
    77     pop_thread3.join();
    78 
    79     return 0;
    80 }
    View Code

    题目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:

     1 #include <iostream>
     2 #include <thread>
     3 #include <mutex>
     4 #include <condition_variable>
     5 using namespace std;
     6 
     7 std::condition_variable cv;
     8 std::mutex metx;
     9 int g_Flag = 0;
    10 int cnt = 0;
    11 bool flag = false;
    12 
    13 int main(void) {
    14     thread t1([&]{
    15         std::unique_lock<std::mutex> lk(metx);
    16         cout << "this is thread1
    ";
    17         g_Flag = 1;
    18         ++cnt;
    19         cv.wait(lk, [&]{{
    20             return flag;
    21         }});
    22         cout << "thread1 exit
    ";
    23     });
    24 
    25     thread t2([&]{
    26         std::unique_lock<std::mutex> lk(metx);
    27         cout << "this is thread2
    ";
    28         g_Flag = 2;
    29         cnt++;
    30         flag = true;
    31         cv.notify_all();
    32         cout << "thread2 exit
    ";
    33     });
    34 
    35     t1.detach();//分离线程
    36     t2.detach();
    37 
    38     std::unique_lock<std::mutex> lc(metx);
    39     cv.wait(lc, [&]{
    40         return cnt >= 2;
    41     });
    42     cout << "main thread exit
    ";
    43 
    44     return 0;
    45 }
    View Code

    代码2:

     1 #include <iostream>
     2 #include <thread>
     3 #include <mutex>
     4 #include <atomic>
     5 #include <future>
     6 using namespace std;
     7 
     8 atomic<int> g_Flag(0), cnt(0);
     9 
    10 void thread1(std::future<int> fu) {
    11     cout << "this is thread1
    ";
    12     g_Flag = 1;
    13     ++cnt;
    14     fu.get();//线程1阻塞至线程2设置共享状态, get等待异步操作结束并返回结果
    15     cout << "thread1 exit
    ";
    16 }
    17 
    18 void thread2(std::promise<int> pro) {
    19     cout << "this is thread2
    ";
    20     g_Flag = 2;
    21     ++cnt;
    22     cout << "thread2 exit
    ";
    23     pro.set_value(1);//设置共享值
    24 }
    25 
    26 int main(void) {
    27     std::promise<int> prom;//创建一个promise对象
    28     std::future<int> fu = prom.get_future();//获得promise内部的future,fut将和prom共享prom中的共享状态
    29 
    30     std::thread t1(thread1, std::move(fu));//通过fut在线程1中得到线程2的状态
    31     std::thread t2(thread2, std::move(prom));//通过prom设置线程2中的共享状态
    32 
    33     t1.detach();
    34     t2.detach();
    35 
    36     while(cnt < 2);
    37     cout << "main thread exit
    ";
    38 
    39     return 0;
    40 }
    View Code
  • 相关阅读:
    T3984 迷宫问题 TJ
    P1091 合唱队形 TJ
    P4549 【模板】裴蜀定理
    牛客NOIP集训一S 牛牛的方程式 TJ
    P3387 【模板】缩点 TJ
    [数字图像处理](三)对数变换
    [数字图像处理](四)直方图均衡化[HE]算法
    [ACM]KMP算法的两种写法,从0开始,从1开始
    [计算几何]补题
    [Servlet]IJ idea搭建Servlet初步
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/8513992.html
Copyright © 2020-2023  润新知