21xrx.com
2024-12-22 20:25:10 Sunday
登录
文章检索 我的文章 写文章
如何在C++中让主线程访问子线程的变量?
2023-07-07 03:04:48 深夜i     --     --
C++ 主线程 子线程 变量 访问

在C++编程中,线程常常被用来处理多任务、异步操作等复杂业务逻辑。而在多线程编程中,主线程需要访问子线程中的变量,这就需要用到线程间同步机制。本文将介绍如何在C++中让主线程访问子线程的变量。

一、使用互斥锁

互斥锁是最常用的保护共享资源的方式。所谓互斥,就是一次只能有一个线程进入临界区(代码段)。当一个线程进入临界区时,它需要先获取锁。如果锁被其他线程占用,它将等待锁被释放。互斥锁可以防止多个线程同时修改共享变量,从而保证数据的一致性。

下面是一个使用互斥锁的示例代码:


#include <thread>

#include <mutex>

std::mutex my_mutex;

void child_thread(int& global_var)

{

  my_mutex.lock();

  global_var = 1;

  my_mutex.unlock();

}

int main()

{

  int global_var = 0;

  std::thread t(child_thread, std::ref(global_var));

  t.join();

  my_mutex.lock();

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

  my_mutex.unlock();

  return 0;

}

上述代码创建了一个子线程t,调用child_thread函数修改共享变量global_var。在主线程中,我们可以使用互斥锁保护global_var变量,防止发生竞争条件。在主线程中,我们需要使用std::ref将global_var传递给子线程,保证修改的是同一个变量。

二、使用条件变量

条件变量是一种线程间通信机制,可以让一个线程等待另一个线程的通知。条件变量的典型用法是:一个线程等待某个变量的值发生改变,另一个线程改变了这个变量的值,并通知等待线程,从而触发后续的处理。

下面是一个使用条件变量的示例代码:


#include <thread>

#include <mutex>

#include <condition_variable>

std::mutex my_mutex;

std::condition_variable cv;

void child_thread(int& global_var)

{

  std::unique_lock<std::mutex> my_lock(my_mutex);

  global_var = 1;

  cv.notify_one();

}

int main()

{

  int global_var = 0;

  std::thread t(child_thread, std::ref(global_var));

  {

    std::unique_lock<std::mutex> my_lock(my_mutex);

    cv.wait(my_lock, [&global_var]() return global_var == 1; );

  }

  t.join();

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

  return 0;

}

上述代码使用条件变量cv和互斥锁my_mutex来保护共享变量global_var,其中cv用于通知等待线程。在子线程中,我们先获取互斥锁my_mutex,改变共享变量global_var的值,然后使用cv.notify_one()函数通知等待线程。在主线程中,我们使用std::unique_lock获取互斥锁my_mutex,然后调用cv.wait进入等待状态,直到global_var变量的值发生改变。当子线程修改完global_var变量后,cv.notify_one()会通知等待线程,从而执行后续处理。

三、使用原子变量

原子变量是一种特殊的变量类型,可以保证对该变量的操作是原子性的,即一次性完成。在多线程编程中,如果多个线程同时访问一个变量,并且对该变量进行修改操作,就有可能发生竞争条件。而原子变量可以保证实现线程安全的访问、读写操作,从而避免竞争条件的发生。

下面是一个使用原子变量的示例代码:


#include <thread>

#include <atomic>

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

void child_thread()

  global_var = 1;

int main()

{

  std::thread t(child_thread);

  t.join();

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

  return 0;

}

上述代码使用std::atomic 来定义原子变量global_var,可以保证对global_var变量的访问是原子的。在子线程中,我们直接修改global_var变量的值即可。在主线程中,我们可以直接访问global_var变量,无需使用锁或条件变量来保护它。

总结

本文介绍了在C++编程中如何让主线程访问子线程的变量。我们可以使用互斥锁、条件变量或原子变量来保护共享变量,避免发生竞争条件,并实现线程安全的访问、读写操作。在实际应用中,我们应根据具体的业务逻辑和数据结构,选择最适合的线程同步机制,保证代码的正确性、可靠性和高效性。

  
  
下一篇: C++ 容器的定义

评论区

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