21xrx.com
2024-12-22 23:41:28 Sunday
登录
文章检索 我的文章 写文章
C++ 线程间通信:实现多线程间的数据交换和同步
2023-07-01 01:12:21 深夜i     --     --
C++ 线程间通信 数据交换 同步 多线程

在C++ 中,使用线程进行异步操作是非常常见的。然而,当涉及到多个线程同时访问和修改共享数据时,就需要使用线程间通信机制来实现数据的同步和交换。本文将介绍在C++ 中实现多线程间数据通信和同步的方法。

1. 互斥锁

互斥锁是最基本的线程同步机制之一。当一个线程申请某个资源时,其他线程必须等待此线程使用完此资源后才能使用。在C++ 中,可以使用std::mutex 来实现互斥锁,std::lock_guard 用来简化锁的管理。

下面是一个使用互斥锁进行线程同步的例子:


#include <iostream>

#include <thread>

#include <mutex>

std::mutex m;

void func()

{

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

  std::cout << "Thread " << std::this_thread::get_id() << " is running." << std::endl;

}

int main()

{

  std::thread t1(func);

  std::thread t2(func);

  t1.join();

  t2.join();

  return 0;

}

以上代码在两个线程中使用std::mutex 串行化输出,保证了对std::cout 对象的访问不会发生冲突。

2. 条件变量

除了互斥锁外,C++ 还提供了另一个基本的线程同步方式:条件变量。条件变量是一种通用的同步机制,可以用于线程间数据的同步和通信。

在C++ 中,可以使用 std::condition_variable 来实现条件变量。使用条件变量需要三个基本操作:

1.等待条件

在等待条件时,线程会在条件变量对象上等待 signal() ,直到其他线程调用了 signal() 方法将其唤醒。

2.通知条件

通知条件时,线程会向条件变量对象发送 signal() ,将处于等待状态的线程唤醒。

3.锁定全局数据

除非数据被锁定,否则条件变量与互斥锁无法正确配合工作。在多线程环境下,需要遵循同步和互斥的原则,保证数据在访问时是线程安全的。

下面是一个使用条件变量进行线程同步的例子:


#include <iostream>

#include <thread>

#include <mutex>

#include <condition_variable>

std::mutex m;

std::condition_variable cv;

bool ready = false;

void worker()

{

  std::unique_lock<std::mutex> lock(m);

  while(!ready)

  {

    cv.wait(lock);

  }

  std::cout << "Worker started working." << std::endl;

}

int main()

{

  std::thread t(worker);

  {

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

    ready = true;

  }

  cv.notify_one();

  t.join();

  return 0;

}

以上代码使用条件变量通知线程,当ready 标志为true 时,唤醒其他线程执行操作。

3. 原子操作

除了互斥锁和条件变量外,C++ 还提供了原子操作作为线程安全的基本操作。

原子操作是一种无锁机制,能够确保对共享数据的修改能够被其他线程正确感知。在C++ 中,可以使用 std::atomic 来创建原子对象。使用原子操作时需要注意:所有修改某个原子对象的线程都必须遵守原子操作需要的同步和互斥规则,否则会出现数据竞争。

下面是一个使用原子操作实现线程同步的例子:


#include <iostream>

#include <thread>

#include <atomic>

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

void worker()

{

  for(int i = 0; i < 5; ++i)

  {

    count.fetch_add(1);

  }

}

int main()

{

  std::thread threads[5];

  for(int i = 0; i < 5; ++i)

  {

    threads[i] = std::thread(worker);

  }

  for(int i = 0; i < 5; ++i)

  {

    threads[i].join();

  }

  std::cout << count << std::endl;

  return 0;

}

以上代码使用std::atomic 对count 进行自增操作并输出结果。使用std::atomic<> 对象可以方便的实现线程间的同步和数据交换。

总结

本文介绍了C++ 中三种实现线程间通信和同步的机制:互斥锁、条件变量和原子操作。这些机制都为多线程程序提供了强大的数据同步保障,可以帮助程序员在多线程的环境下更好地管理和操作共享数据。同时,程序员需要学习这些机制的使用方法和原理,才能更好地理解和利用多线程技术。

  
  

评论区

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