21xrx.com
2025-03-27 03:23:06 Thursday
文章检索 我的文章 写文章
C++: 探索3种线程同步方法
2023-07-09 12:34:42 深夜i     --     --
C++ 线程 同步 方法 探索

C++语言可用于开发多线程应用程序,实现并发执行多个任务。然而线程之间的交互会产生竞争条件,因此需要实现线程同步,以确保线程安全和程序正确性。本文将探讨三种C++中常见的线程同步方法。

1. 互斥量

互斥量是C++中用于实现线程同步的最基本的机制之一。它可以将共享资源封装在一个锁定的代码块中,保证只有一个线程在任何时候都可以访问它。通常使用互斥量来保护共享数据结构、文件、设备等。

以下是互斥量的示例代码:

#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void print(int n) {
  mtx.lock();
  std::cout << "Number: " << n << std::endl;
  mtx.unlock();
}
int main() {
  std::thread t1(print, 1);
  std::thread t2(print, 2);
  t1.join();
  t2.join();
  return 0;
}

在这个示例代码中,使用了互斥量mtx来保护共享的输出语句,以便只有一个线程在任何时候都可以访问它。线程t1和t2在被创建后,都会调用print函数,但只有一个线程能够获得互斥量的锁并输出。

2. 条件变量

条件变量是C++中一种更高级的线程同步机制,用于解决互斥量无法解决的问题。当一个线程需要等待某个条件满足后再继续执行时,可以使用条件变量。

以下是条件变量的示例代码:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void print() {
  std::unique_lock<std::mutex> lck(mtx);
  while (!ready) {
    cv.wait(lck);
  }
  std::cout << "Hello, World!" << std::endl;
}
void setData() {
  std::this_thread::sleep_for(std::chrono::seconds(1));
  ready = true;
  cv.notify_one();
}
int main() {
  std::thread t1(print);
  std::thread t2(setData);
  t1.join();
  t2.join();
  return 0;
}

在这个示例代码中,线程t1在等待ready变量为true时调用了条件变量的wait方法进行阻塞,当线程t2将ready变量设置为true时,调用条件变量的notify_one方法来通知t1继续执行输出语句。

3. 原子操作

原子操作是C++中另一种常见的线程同步机制,用于对原始数据类型进行操作,可以保证操作的完整性和一致性。原子操作常用于实现多线程计数器、队列等数据结构。

以下是原子操作的示例代码:

#include <iostream>
#include <thread>
#include <atomic>
std::atomic<int> counter(0);
void increment() {
  for (int i = 0; i < 1000000; ++i) {
    counter++;
  }
}
void decrement() {
  for (int i = 0; i < 1000000; ++i)
    counter--;
  
}
int main() {
  std::thread t1(increment);
  std::thread t2(decrement);
  t1.join();
  t2.join();
  std::cout << "Final value: " << counter << std::endl;
  return 0;
}

在这个示例代码中,两个线程分别对共享的计数器counter执行加1和减1操作,由于原子操作可以确保操作的完整性和一致性,因此不会出现竞争条件和数据损坏的情况。

综上,C++中提供了多种线程同步机制,包括互斥量、条件变量和原子操作等。开发者应根据自己的应用场景和需求来选择适合的线程同步方法,以确保程序的正确性和线程安全。

  
  

评论区