21xrx.com
2025-06-18 21:07:26 Wednesday
文章检索 我的文章 写文章
如何在C++多线程中访问共享资源并回调函数?
2023-07-01 20:13:46 深夜i     16     0
C++多线程 共享资源 回调函数 访问 解决方案

C++是一种强大的编程语言,具有许多功能和特性,其中之一就是多线程编程。在多线程编程中,可能会有多个线程访问相同的资源和变量,这就需要使用同步和互斥机制来保护共享数据的完整性。本文将介绍在C++多线程中如何访问共享资源并回调函数。

1.使用互斥锁

互斥锁是最常用的同步机制之一,它将临界区封装在一起,只允许一个线程访问共享资源。在C++中,可以使用std::mutex类来实现互斥锁。以下是一个简单的例子:

#include <iostream>
#include <thread>
#include <mutex>
std::mutex mutex;
int sharedData = 0;
void doSomething(int id) {
 for(int i = 0; i < 5; i++) {
  std::unique_lock<std::mutex> lock(mutex); //获取锁
  sharedData++;
  std::cout << "Thread " << id << " adds 1 to sharedData, sharedData = " << sharedData << std::endl;
  lock.unlock(); //释放锁
 }
}
int main() {
 std::thread t1(doSomething, 1);
 std::thread t2(doSomething, 2);
 t1.join();
 t2.join();
 return 0;
}

在这个例子中,使用std::mutex类实现了互斥锁,使用unique_lock获取和释放锁,并在临界区内访问共享资源。

2.使用条件变量

条件变量是一种同步机制,允许线程按照特定的条件等待或者唤醒。在C++中,可以使用std::condition_variable类实现条件变量。以下是一个简单的例子:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mutex;
std::condition_variable cond;
int sharedData = 0;
bool dataReady = false;
void doSomething(int id) {
 for(int i = 0; i < 5; i++) {
  std::unique_lock<std::mutex> lock(mutex);
  while(!dataReady) { //等待条件变量
   cond.wait(lock);
  }
  sharedData++;
  std::cout << "Thread " << id << " adds 1 to sharedData, sharedData = " << sharedData << std::endl;
  dataReady = false;
  lock.unlock();
  cond.notify_one(); //唤醒等待条件变量的线程
 }
}
void sendData() {
 for(int i = 0; i < 5; i++) {
  std::unique_lock<std::mutex> lock(mutex);
  while(dataReady) { //等待条件变量
   cond.wait(lock);
  }
  std::cout << "Main thread sends data" << std::endl;
  dataReady = true;
  lock.unlock();
  cond.notify_one(); //唤醒等待条件变量的线程
 }
}
int main() {
 std::thread t1(doSomething, 1);
 std::thread t2(doSomething, 2);
 sendData();
 t1.join();
 t2.join();
 return 0;
}

在这个例子中,使用std::condition_variable类实现了条件变量,使用wait和notify_one等待和唤醒线程,并在临界区内访问共享资源。

3.回调函数

回调函数是一种常用的编程技术,它允许函数将另一个函数作为参数,并在适当的时候调用该函数。在多线程编程中,回调函数可以用于在线程完成某个任务后通知另一个线程。以下是一个简单的例子:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
std::mutex mutex;
std::condition_variable cond;
bool taskDone = false;
void doTask(std::function<void()> callback) {
 std::cout << "Task starts" << std::endl;
 std::this_thread::sleep_for(std::chrono::seconds(2)); //模拟任务执行
 std::unique_lock<std::mutex> lock(mutex);
 taskDone = true;
 callback(); //执行回调函数
}
void callback() {
 std::unique_lock<std::mutex> lock(mutex);
 std::cout << "Callback starts" << std::endl;
 taskDone = true;
}
int main() {
 std::thread t(doTask, callback);
 std::unique_lock<std::mutex> lock(mutex);
 while(!taskDone) {
  cond.wait(lock);
 }
 std::cout << "Main thread finishes" << std::endl;
 t.join();
 return 0;
}

在这个例子中,使用std::function类实现了回调函数,在doTask函数中执行任务,并在任务完成后执行回调函数。

综上所述,使用互斥锁和条件变量来同步线程,同时使用回调函数来通知线程完成任务是在C++多线程中访问共享资源并回调函数的常用方法。开发人员可以根据具体的需求选择适当的同步机制和回调函数实现。

  
  

评论区