线程同步是指同一进程中的多个线程互相协调工作从而达到一致性。之所以需要线程同步,是因为多个线程同时对一个数据对象进行修改操作时,可能会对数据造成破坏,下面是多个线程同时修改同一数据造成破坏的例子:


c++实现多线程同步_#include



1 #include <thread>
 2 #include <iostream>
 3 
 4 void Fun_1(unsigned int &counter);
 5 void Fun_2(unsigned int &counter);
 6 
 7 int main()
 8 {
 9     unsigned int counter = 0;
10     std::thread thrd_1(Fun_1, counter);
11     std::thread thrd_2(Fun_2, counter);
12     thrd_1.join();
13     thrd_2.join();
14     system("pause");
15     return 0;
16 }
17 
18 void Fun_1(unsigned int &counter)
19 {
20     while (true)
21     {
22         ++counter;
23         if (counter < 1000)
24         {
25             std::cout << "Function 1 counting " << counter << "...\n";
26         }
27         else
28         {
29             break;
30         }
31     }
32 }
33 
34 void Fun_2(unsigned int &counter)
35 {
36     while (true)
37     {
38         ++counter;
39         if (counter < 1000)
40         {
41             std::cout << "Function 2 counting " << counter << "...\n";
42         }
43         else
44         {
45             break;
46         }
47     }
48 }



c++实现多线程同步_#include


      运行结果如图所示:

c++实现多线程同步_线程同步_03

      显然输出的结果存在问题,变量并没有按顺序递增,所以线程同步是很重要的。在这里记录三种线程同步的方式:

  ①使用C++标准库的thread、mutex头文件:


1 #include <thread>
 2 #include <mutex>
 3 #include <iostream>
 4 
 5 void Fun_1();
 6 void Fun_2();
 7 
 8 unsigned int counter = 0;
 9 std::mutex mtx;
10 
11 int main()
12 {
13     std::thread thrd_1(Fun_1);
14     std::thread thrd_2(Fun_2);
15     thrd_1.join();
16     thrd_2.join();
17     system("pause");
18     return 0;
19 }
20 
21 void Fun_1()
22 {
23     while (true)
24     {
25         std::lock_guard<std::mutex> mtx_locker(mtx);
26         ++counter;
27         if (counter < 1000)
28         {
29             std::cout << "Function 1 counting " << counter << "...\n";
30         }
31         else
32         {
33             break;
34         }
35     }
36 }
37 
38 void Fun_2()
39 {
40     while (true)
41     {
42         std::lock_guard<std::mutex> mtx_locker(mtx);
43         ++counter;
44         if (counter < 1000)
45         {
46             std::cout << "Function 2 counting " << counter << "...\n";
47         }
48         else
49         {
50             break;
51         }
52     }
53 }



std::lock_guard<std::mutex> mtx_locker(mtx); 在C++中,通过构造std::mutex的实例来创建互斥元,可通过调用其成员函数lock()和unlock()来实现加锁和解锁,然后这是不推荐的做法,因为这要求程序员在离开函数的每条代码路径上都调用unlock(),包括由于异常所导致的在内。作为替代,标准库提供了std::lock_guard类模板,实现了互斥元的RAII惯用语法(资源获取即初始化)。该对象在构造时锁定所给的互斥元,析构时解锁该互斥元,从而保证被锁定的互斥元始终被正确解锁。代码运行结果如下图所示,可见得到了正确的结果。

c++实现多线程同步_#include_04