C++使用thread类多线程编程 C++使用thread类多线程编程

C++使用thread类多线程编程

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


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


输出:


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


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

输出:


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


带参子线程


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

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

输出跟上例输出一样:



多线程数据竞争


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

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

输出结果(部分):



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

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

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

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

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



版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/dcrmg/article/details/53912941

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


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


输出:


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


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

输出:


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


带参子线程


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

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

输出跟上例输出一样:



多线程数据竞争


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

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

输出结果(部分):



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

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

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

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

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



猜你喜欢

转载自blog.csdn.net/jfkidear/article/details/80922316