21xrx.com
2024-11-08 22:05:39 Friday
登录
文章检索 我的文章 写文章
C++多线程同步的几种实现方法
2023-07-03 17:13:48 深夜i     --     --
C++多线程 同步实现方法 互斥量 条件变量 信号量

在C++中,多线程同步是非常重要的,因为在多线程环境中,线程之间很容易相互干扰,导致数据错误或者死锁的情况发生。为了避免这些问题,我们需要采用一些同步方法来协调线程之间的操作。下面是几种常用的C++多线程同步方法。

1.互斥锁

互斥锁是最常用的同步方法之一,可以用来保证线程安全。当一个线程获得互斥锁时,其他线程就无法获得它,直到该线程释放了该锁。这样就可以避免多个线程同时访问共享资源的问题。

例如:


#include <thread>

#include <mutex>

std::mutex mtx;

void threadFunc(int& n)

{

  std::lock_guard<std::mutex> lock(mtx);

  ++n;

}

int main()

{

  int n = 0;

  std::thread t1(threadFunc, std::ref(n));

  std::thread t2(threadFunc, std::ref(n));

  t1.join();

  t2.join();

  return 0;

}

在上面的代码中,我们使用了std::mutex来定义互斥锁,然后在线程函数中使用std::lock_guard来保护共享资源n。

2.条件变量

条件变量是一种线程同步工具,用于在线程之间传递信号。当线程需要等待某个条件发生时,它可以调用条件变量的wait()方法,该方法会使线程休眠直到另一个线程调用该条件变量的notify_one或notify_all方法。当条件发生时,notify_one或notify_all会唤醒等待的线程。

例如:


#include <thread>

#include <condition_variable>

#include <iostream>

std::condition_variable cv;

void threadFunc(int& n)

{

  std::unique_lock<std::mutex> ulock(mtx);

  cv.wait(ulock, [] return n == 1; );

  std::cout << "Thread ID " << std::this_thread::get_id() << " wake up!" << std::endl;

}

int main()

{

  int n = 0;

  std::thread t1(threadFunc, std::ref(n));

  std::thread t2([&n] {

    std::this_thread::sleep_for(std::chrono::seconds(1));

    n = 1;

    cv.notify_one();

  });

  t1.join();

  return 0;

}

在这个例子中,我们使用了std::condition_variable和std::unique_lock 来定义一个条件变量和锁。线程t1调用wait()方法等待条件发生,线程t2调用notify_one()来通知t1当n等于1时条件发生,t1就会被唤醒。

3.原子类型

原子类型是一种线程安全的数据类型,可以保证在多线程环境下对其进行操作时不会出现竞态条件。在C++11中,原子类型有很多种,如std::atomic 、std::atomic 等。使用原子类型可以避免使用互斥锁等同步方法。

例如:


#include <thread>

#include <atomic>

#include <iostream>

std::atomic<int> n(0);

void threadFunc1()

{

  n++;

}

void threadFunc2()

  n--;

int main()

{

  std::thread t1(threadFunc1);

  std::thread t2(threadFunc2);

  t1.join();

  t2.join();

  std::cout << n << std::endl;

  return 0;

}

在上面的代码中,我们使用了std::atomic 来定义原子变量n,保证n++和n--操作的原子性。

总之,以上是几种常用的C++多线程同步方法。在实际编程过程中,需要根据具体情况来选择适合的同步方式。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复