21xrx.com
2024-11-22 07:23:04 Friday
登录
文章检索 我的文章 写文章
如何在C++多线程中访问共享资源并回调函数?
2023-07-01 20:13:46 深夜i     --     --
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++多线程中访问共享资源并回调函数的常用方法。开发人员可以根据具体的需求选择适当的同步机制和回调函数实现。

  
  

评论区

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