21xrx.com
2024-12-28 05:00:46 Saturday
登录
文章检索 我的文章 写文章
C++中实现线程间的数据共享
2023-07-08 11:24:14 深夜i     --     --
C++ 线程 数据共享

C++是一种高级编程语言,已经成为了许多软件开发项目的首选语言。在C++开发中,线程是一个非常重要的概念,可以实现多任务并发执行。但是,在多个并发执行的线程中,数据的共享和同步问题仍然是非常关键的。因此,在本文中,我们将探讨如何在C++中实现线程间的数据共享。

一、使用互斥锁

互斥锁是一种并发编程同步原语,可保护共享资源免受并发访问的影响。在C++中,可以使用mutex类来实现互斥锁。当一个线程想要访问共享变量时,它必须先获取互斥锁。如果另一个线程已经获取了锁,则当前线程必须等待直到另一个线程释放锁。

下面是一个示例代码,演示了如何使用互斥锁实现线程间的数据共享:

 c++

#include <iostream>

#include <thread>

#include <mutex>

using namespace std;

mutex mtx;

int shared_var = 0;

void increment_shared_var(int n)

{

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

    mtx.lock();

    ++shared_var;

    mtx.unlock();

  }

}

int main()

{

  thread t1(increment_shared_var, 1000000);

  thread t2(increment_shared_var, 1000000);

  t1.join();

  t2.join();

  cout << "shared_var = " << shared_var << endl;

  return 0;

}

在这个示例中,我们使用了mutex互斥锁来保护shared_var共享变量。两个线程t1和t2会调用increment_shared_var函数,在函数中对shared_var变量进行加操作。使用互斥锁可以确保每个线程在访问共享变量之前获取了锁,并在其访问结束时释放了锁。这样就可以避免两个线程同时写入shared_var的情况。最后,我们输出shared_var的值,并保证其等于2000000。

二、使用信号量

信号量是一个计数器,用于控制多任务访问共享资源。在C++中,可以使用简单的信号量类实现信号量。当一个线程希望访问共享资源时,它必须等待信号量计数为1。如果计数为0,则线程将阻塞在该信号量上,直到另一个线程释放信号量为止。

下面是一个示例代码,演示了如何使用信号量实现线程间的数据共享:

 c++

#include <iostream>

#include <thread>

#include <semaphore.h>

using namespace std;

sem_t sem;

int shared_var = 0;

void increment_shared_var(int n)

{

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

    sem_wait(&sem);

    ++shared_var;

    sem_post(&sem);

  }

}

int main()

{

  sem_init(&sem, 0, 1);

  thread t1(increment_shared_var, 1000000);

  thread t2(increment_shared_var, 1000000);

  t1.join();

  t2.join();

  sem_destroy(&sem);

  cout << "shared_var = " << shared_var << endl;

  return 0;

}

在这个示例中,我们使用了semaphore信号量来保护shared_var共享变量。两个线程t1和t2调用increment_shared_var函数,在函数中对shared_var变量进行加操作。将信号量计数设置为1,可以确保只有一个线程可以访问共享资源。在访问之前调用sem_wait操作,并在访问之后调用sem_post操作。操作保证只有在计数为1时才会执行,从而避免了两个线程同时写入shared_var的情况。最后,我们输出shared_var的值,并保证其等于2000000。

综上所述,使用互斥锁和信号量是在C++中实现线程间的数据共享的两种常见方法。需要根据具体的情况选择使用哪种同步机制,以确保数据共享的正确性和效率。

  
  

评论区

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