std::thread() 多线程使用及其同步操作

在声明一个std::thread对象之后,都可以使用detach和join函数来启动被调线程,区别在于两者是否阻塞主调线程。

(1)当使用join()函数时,主调线程阻塞,等待被调线程终止,然后主调线程回收被调线程资源,并继续运行;

(2)当使用detach()函数时,主调线程继续运行,被调线程驻留后台运行,主调线程无法再取得该被调线程的控制权。当主调线程结束时,由运行时库负责清理与被调线程相关的资源。

 

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

 

 
  1. #include

  2. #include

  3. #include

  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. }

 

输出:

std::thread() 多线程使用及其同步操作_第1张图片

 

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

 

 
  1. #include

  2. #include

  3. #include

  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. }

 

输出:

std::thread() 多线程使用及其同步操作_第2张图片

 

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

 

带参子线程

 

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

 

 
  1. #include

  2. #include

  3. #include

  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. }

 

 

输出跟上例输出一样:

std::thread() 多线程使用及其同步操作_第3张图片

 

多线程数据竞争

 

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

 

 
  1. #include

  2. #include

  3. #include

  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. }


输出结果(部分):

 

std::thread() 多线程使用及其同步操作_第4张图片

 

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

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

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

 

 
  1. #include

  2. #include

  3. #include

  4. #include

  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互斥对象之后输出正常:

 

std::thread() 多线程使用及其同步操作_第5张图片

你可能感兴趣的:(std::thread() 多线程使用及其同步操作)