zoukankan      html  css  js  c++  java
  • C++使用thread类多线程编程

    原文:http://blog.csdn.net/dcrmg/article/details/53912941

    C++11中引入了一个用于多线程操作的thread类,简单多线程示例:

    [cpp] view plain copy
     
     print?
    1. #include <iostream>  
    2. #include <thread>  
    3. #include <Windows.h>  
    4.   
    5. using namespace std;  
    6.   
    7. void thread01()  
    8. {  
    9.     for (int i = 0; i < 5; i++)  
    10.     {  
    11.         cout << "Thread 01 is working !" << endl;  
    12.         Sleep(100);  
    13.     }  
    14. }  
    15. void thread02()  
    16. {  
    17.     for (int i = 0; i < 5; i++)  
    18.     {  
    19.         cout << "Thread 02 is working !" << endl;  
    20.         Sleep(200);  
    21.     }  
    22. }  
    23.   
    24. int main()  
    25. {  
    26.     thread task01(thread01);  
    27.     thread task02(thread02);  
    28.     task01.join();  
    29.     task02.join();  
    30.   
    31.     for (int i = 0; i < 5; i++)  
    32.     {  
    33.         cout << "Main thread is working !" << endl;  
    34.         Sleep(200);  
    35.     }  
    36.     system("pause");  
    37. }  

    输出:

    两个子线程并行执行,join函数会阻塞主流程,所以子线程都执行完成之后才继续执行主线程。可以使用detach将子线程从主流程中分离,独立运行,不会阻塞主线程:

    [cpp] view plain copy
     
     print?
    1. #include <iostream>  
    2. #include <thread>  
    3. #include <Windows.h>  
    4.   
    5. using namespace std;  
    6.   
    7. void thread01()  
    8. {  
    9.     for (int i = 0; i < 5; i++)  
    10.     {  
    11.         cout << "Thread 01 is working !" << endl;  
    12.         Sleep(100);  
    13.     }  
    14. }  
    15. void thread02()  
    16. {  
    17.     for (int i = 0; i < 5; i++)  
    18.     {  
    19.         cout << "Thread 02 is working !" << endl;  
    20.         Sleep(200);  
    21.     }  
    22. }  
    23.   
    24. int main()  
    25. {  
    26.     thread task01(thread01);  
    27.     thread task02(thread02);  
    28.     task01.detach();  
    29.     task02.detach();  
    30.   
    31.     for (int i = 0; i < 5; i++)  
    32.     {  
    33.         cout << "Main thread is working !" << endl;  
    34.         Sleep(200);  
    35.     }  
    36.     system("pause");  
    37. }  
     
    输出:

    使用detach的主线程和两个子线程并行执行。

    带参子线程

    在绑定的时候也可以同时给带参数的线程传入参数:

    [cpp] view plain copy
     
     print?
    1. #include <iostream>  
    2. #include <thread>  
    3. #include <Windows.h>  
    4.   
    5. using namespace std;  
    6.   
    7. //定义带参数子线程  
    8. void thread01(int num)  
    9. {  
    10.     for (int i = 0; i < num; i++)  
    11.     {  
    12.         cout << "Thread 01 is working !" << endl;  
    13.         Sleep(100);  
    14.     }  
    15. }  
    16. void thread02(int num)  
    17. {  
    18.     for (int i = 0; i < num; i++)  
    19.     {  
    20.         cout << "Thread 02 is working !" << endl;  
    21.         Sleep(200);  
    22.     }  
    23. }  
    24.   
    25. int main()  
    26. {  
    27.     thread task01(thread01, 5);  //带参数子线程  
    28.     thread task02(thread02, 5);  
    29.     task01.detach();  
    30.     task02.detach();  
    31.   
    32.     for (int i = 0; i < 5; i++)  
    33.     {  
    34.         cout << "Main thread is working !" << endl;  
    35.         Sleep(200);  
    36.     }  
    37.     system("pause");  
    38. }  

    输出跟上例输出一样:

    多线程数据竞争

    多个线程同时对同一变量进行操作的时候,如果不对变量做一些保护处理,有可能导致处理结果异常:

    [cpp] view plain copy
     
     print?
    1. #include <iostream>  
    2. #include <thread>  
    3. #include <Windows.h>  
    4.   
    5. using namespace std;  
    6.   
    7. int totalNum = 100;  
    8.   
    9. void thread01()  
    10. {  
    11.     while (totalNum > 0)  
    12.     {  
    13.         cout << totalNum << endl;  
    14.         totalNum--;  
    15.         Sleep(100);  
    16.     }  
    17. }  
    18. void thread02()  
    19. {  
    20.     while (totalNum > 0)  
    21.     {  
    22.         cout << totalNum << endl;  
    23.         totalNum--;  
    24.         Sleep(100);  
    25.     }  
    26. }  
    27.   
    28. int main()  
    29. {  
    30.     thread task01(thread01);  
    31.     thread task02(thread02);  
    32.     task01.detach();  
    33.     task02.detach();  
    34.     system("pause");  
    35. }  


    输出结果(部分):

    有两个问题,一是有很多变量被重复输出了,而有的变量没有被输出;二是正常情况下每个线程输出的数据后应该紧跟一个换行符,但这里大部分却是另一个线程的输出。

    这是由于第一个线程对变量操作的过程中,第二个线程也对同一个变量进行各操作,导致第一个线程处理完后的输出有可能是线程二操作的结果。针对这种数据竞争的情况,可以使用线程互斥对象mutex保持数据同步。

    mutex类的使用需要包含头文件mutex:

    [cpp] view plain copy
     
     print?
    1. #include <iostream>  
    2. #include <thread>  
    3. #include <Windows.h>  
    4. #include <mutex>  
    5.   
    6. using namespace std;  
    7.   
    8. mutex mu;  //线程互斥对象  
    9.   
    10. int totalNum = 100;  
    11.   
    12. void thread01()  
    13. {  
    14.     while (totalNum > 0)  
    15.     {  
    16.         mu.lock(); //同步数据锁  
    17.         cout << totalNum << endl;  
    18.         totalNum--;  
    19.         Sleep(100);  
    20.         mu.unlock();  //解除锁定  
    21.     }  
    22. }  
    23. void thread02()  
    24. {  
    25.     while (totalNum > 0)  
    26.     {  
    27.         mu.lock();  
    28.         cout << totalNum << endl;  
    29.         totalNum--;  
    30.         Sleep(100);  
    31.         mu.unlock();  
    32.     }  
    33. }  
    34.   
    35. int main()  
    36. {  
    37.     thread task01(thread01);  
    38.     thread task02(thread02);  
    39.     task01.detach();  
    40.     task02.detach();  
    41.     system("pause");  
    42. }  


    多线程中加入mutex互斥对象之后输出正常:

  • 相关阅读:
    Java抽象类、接口能否有构造方法
    Java堆溢出、栈溢出示例
    typora常用快捷键
    什么是业务逻辑
    解决idea登录github出现的invalid authentication data 404 not found
    SQL常用聚合函数
    oracle存储过程/函数调试
    解决IDEA全局搜索Ctrl+Shift+F失效问题
    如何在win10系统中使用Linux命令
    Java复现NullPointerException异常
  • 原文地址:https://www.cnblogs.com/lizhigang/p/7324112.html
Copyright © 2011-2022 走看看