zoukankan      html  css  js  c++  java
  • C++多线程chap2多线程通信和同步1

    这里,只是记录自己的学习笔记。

    顺便和大家分享多线程的基础知识。然后从入门到实战。有代码。

    知识点来源:

    https://edu.51cto.com/course/26869.html


    1.多线程同步通信

    1.1多线程状态

    1.1.1线程状态说明:

    •   初始化 ( Init ) :该线程正在创建。
    •   就绪 ( Ready ):该线程在继续列表中,等待CPU调度。
    •   运行 (Running):该线程正在运行。
    •   阻塞 ( Blocked ):该线程被阻塞挂起。Blocked状态包括:pend(锁、事件、信号量等阻塞)、suspend(主动pend)、delay(延时阻塞)、pendtime(因为锁、事件、信号量时间等 超时等待)。
    •   退出  ( Exit ) :该线程运行结束,等待父线程回收其控制块资源。

    1.1.2 竞争状态(Race Condition)和临界区(Critical Section)

    竞争状态(Race Condition)

    • 多线程同时读写共享数据。

    临界区(Critical Section)

    • 读写共享数据的代码片段

    避免竞争状态策略,对临界区进行保护,同时只能有一个线程进入临界区。

    mutex 的 lock()  和 try_lock()  方法的使用。

     1 #include <iostream>
     2 #include <thread>
     3 #include <string>
     4 #include <mutex>
     5 using namespace std;
     6 static mutex mux;
     7 
     8 void TestThread() {
     9     
    10     //对于锁,尽可能晚的申请;尽可能早的释放。。。
    11 
    12     //获取锁资源,如果没有则阻塞等待
    13     mux.lock();//处于阻塞状态,cpu资源是释放的。。。
    14     cout << "========================================" << endl;
    15     cout << "test 001" << endl;
    16     cout << "test 002" << endl;
    17     cout << "test 003" << endl;
    18     cout << "========================================" << endl;
    19     mux.unlock();
    20 }
    21 
    22 
    23 void TestThread2() {
    24 
    25     for (;;) {
    26         //注意,调用 try_lock 是有开销的,在try_lock之后,必须跟一个sleep_for等待若干时间(释放cpu资源),否则一直try_lock会把cpu资源耗尽。
    27         if (!mux.try_lock()) {
    28             cout << "....." <<flush<< endl;
    29             this_thread::sleep_for(3000ms);
    30             continue;
    31         }
    32         cout << "========================================" << endl;
    33         cout << "test 001" << endl;
    34         cout << "test 002" << endl;
    35         cout << "test 003" << endl;
    36         cout << "========================================" << endl;
    37         mux.unlock();
    38         this_thread::sleep_for(1000ms);
    39     }
    40 }
    41 
    42 
    43 
    44 int main()
    45 {
    46     //for (int i = 0; i < 10; i++) {
    47     //    thread th(TestThread);
    48     //    th.detach();
    49     //}
    50 
    51     for (int i = 0; i < 10; i++) {
    52         thread th(TestThread2);
    53         th.detach();
    54     }
    55 
    56     getchar();
    57     return 0;
    58 }

    互斥锁等待坑,线程抢占不到资源.

    特别注意,unlock之后,不要再立即进入lock。预留一点时间出来。

     1 #include <iostream>
     2 #include <thread>
     3 #include <string>
     4 #include <mutex>
     5 using namespace std;
     6 
     7 //互斥锁等待坑,线程抢占不到资源
     8 static mutex mux;
     9 
    10 void ThreradMainMux(int i) {
    11     //
    12     for (;;) {
    13 
    14         mux.lock();
    15         cout << i << "[in]" << endl;
    16         this_thread::sleep_for(1000ms);
    17         mux.unlock();
    18 
    19         //特别注意,unlock之后,不要再立即进入lock。预留一点时间出来。
    20         this_thread::sleep_for(1ms);
    21     }
    22 }
    23 
    24 int main() {
    25     for (int i = 0; i < 3; i++)
    26     {
    27         thread th(ThreradMainMux,i);
    28         th.detach();
    29     }
    30 
    31     getchar();
    32     return 0;
    33 }
    超时锁的应用 timed_mutex(避免长时间死锁)
     1 #include <iostream>
     2 #include <string>
     3 #include <mutex>
     4 #include <thread>
     5 using namespace std;
     6 
     7 
     8 
     9 //超时锁的应用 timed_mutex(避免长时间死锁)
    10 
    11 timed_mutex  tmux;
    12 
    13 void ThreadMainTime(int i) {
    14     for (;;) {
    15         if (!tmux.try_lock_for(std::chrono::milliseconds(1000))) {
    16             cout << i << "[try_lock_for] timeout" << endl;
    17             continue;
    18         }
    19         cout << i << "[in]" << endl;
    20 
    21         this_thread::sleep_for(2000ms);
    22         tmux.unlock();
    23         this_thread::sleep_for(1ms);
    24     }
    25 }
    26 
    27 
    28 int main() {
    29 
    30     for (int i = 0; i < 3; i++) {
    31         thread th(ThreadMainTime, i);
    32 
    33         th.detach();
    34     }
    35 
    36     getchar();
    37     return 0;
    38 }

    //递归锁(可重入) recursive mutex 和 recursive_timed_mutex 用于业务组合


    // 同一个线程中的同一把锁可以锁多次,避免了一些不必要的死锁
    //组合业务,用到同一把锁

     1 #include <iostream>
     2 #include <string>
     3 #include <thread>
     4 #include <mutex>
     5 using namespace std;
     6 //递归锁(可重入) recursive mutex 和 recursive_timed_mutex 用于业务组合
     7 
     8 
     9 // 同一个线程中的同一把锁可以锁多次,避免了一些不必要的死锁
    10 //组合业务,用到同意把锁
    11 recursive_mutex rmux;
    12 
    13 
    14 void Task1() {
    15     rmux.lock();
    16     cout << "task1  [in]" << endl;
    17     rmux.unlock();
    18 }
    19 
    20 
    21 void Task2() {
    22     rmux.lock();
    23     cout << "task2  [in]" << endl;
    24     rmux.unlock();
    25 }
    26 
    27 
    28 void ThreadMainRec(int i) {
    29     for (;;) {
    30         rmux.lock();
    31         Task1();
    32         cout << i << "[in]" << endl;
    33         this_thread::sleep_for(2000ms);
    34         Task2();
    35         rmux.unlock();
    36         this_thread::sleep_for(1ms);
    37     }
    38 }
    39 
    40 
    41 int main() {
    42     for (int i = 0; i < 3; i++) {
    43         thread th(ThreadMainRec, i);
    44         th.detach();
    45     }
    46 
    47 
    48     getchar();
    49     return 0;
    50 }

     

     

    作者:小乌龟
    【转载请注明出处,欢迎转载】 希望这篇文章能帮到你

     

  • 相关阅读:
    python字符串,数组操作
    python爬虫之有道在线翻译
    英雄联盟界面
    学习photoshop心得
    linux命令总结之lsof命令
    linux命令总结之netstat命令
    linux命令总结之route命令
    linux命令总结之ip命令
    linux命令总结之dig命令
    IP地址的分类——a,b,c 类是如何划分的
  • 原文地址:https://www.cnblogs.com/music-liang/p/15587259.html
Copyright © 2011-2022 走看看