21xrx.com
2024-11-05 22:51:11 Tuesday
登录
文章检索 我的文章 写文章
如何在C++中让子线程调用主线程
2023-07-05 10:19:50 深夜i     --     --
C++多线程编程 子线程与主线程 线程同步与通信 wait()和notify()函数 互斥锁和

在C++中,通过线程的创建和管理可以实现多线程编程。线程通常是由主线程创建的子线程,子线程可以并发执行不同的任务。在某些情况下,子线程需要调用主线程来完成一些需要主线程完成的操作,那么如何在C++中让子线程调用主线程呢?

方法一:使用互斥锁和条件变量实现线程同步

在C++中,可以使用互斥锁和条件变量实现线程的同步与通信。在主线程中使用互斥锁和条件变量来等待子线程的信号,子线程完成任务后发送信号给主线程。具体实现方法如下:


#include <iostream>

#include <thread>

#include <mutex>

#include <condition_variable>

std::mutex g_mutex;

std::condition_variable g_cv;

bool g_flag = false;

void subThreadHandler(int& data) {

  // 模拟子线程完成任务

  for (int i = 0; i < 10; ++i) {

    ++data;

  }

  // 发送信号给主线程

  g_flag = true;

  g_cv.notify_one();

}

int main() {

  int data = 0;

  std::thread subThread(subThreadHandler, std::ref(data));

  // 等待子线程信号

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

  while (!g_flag) {

    g_cv.wait(lock);

  }

  std::cout << "data=" << data << std::endl;

  subThread.join();

  return 0;

}

在子线程中完成任务后,使用`g_flag`变量标记任务完成,并通过`g_cv.notify_one()`发送信号给主线程。在主线程中使用`std::unique_lock lock(g_mutex);`创建锁保证线程安全,并使用`while (!g_flag) { g_cv.wait(lock); }`等待子线程的信号。一旦收到子线程的信号,主线程就可以继续执行。

方法二:使用`std::async`异步函数实现线程同步

`std::async`是C++11标准中提供的异步函数,它可以创建异步任务(例如一个子线程),并返回一个`std::future`对象。通过`std::future`对象可以获取异步任务的返回值,以及在异步任务完成后执行某些操作。在主线程中创建`std::future`对象并调用`get()`函数等待子线程完成任务,并获取子线程的任务结果。具体实现方法如下:


#include <iostream>

#include <future>

int subTask(int data) {

  // 模拟子线程完成任务

  for (int i = 0; i < 10; ++i) {

    ++data;

  }

  return data;

}

int main() {

  int data = 0;

  // 创建异步任务并等待任务完成

  std::future<int> fut = std::async(std::launch::async, subTask, data);

  data = fut.get();

  std::cout << "data=" << data << std::endl;

  return 0;

}

`std::async`函数接受三个参数,第一个参数是任务启动方式(是异步启动还是同步启动),第二个参数是执行的任务函数,第三个参数是任务函数的参数。在主线程中等待异步任务的完成,可以通过`std::future`对象的`get()`函数获取任务结果。通过这种方式,子线程可以调用主线程,并且可以直接返回结果。

  
  

评论区

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