21xrx.com
2024-11-05 14:47:22 Tuesday
登录
文章检索 我的文章 写文章
如何在C++中使用多线程加锁?
2023-07-13 02:46:56 深夜i     --     --
C++ 多线程 加锁

在C++中,多线程编程是一种常用而重要的技术。但是,多线程编程中的资源竞争问题往往是比较常见的问题。其中,锁机制是使用多线程编程的一种关键技术,可以解决资源竞争问题。那么,下面就让我们了解一下如何在C++中使用多线程加锁。

一、深入理解锁机制

在进行多线程编程时,线程之间的访问是可能会产生资源冲突的。为了解决这一问题,我们可以使用锁机制。这个机制其基本思想是:一个线程在访问被锁住的资源时,其他线程必须等待锁被释放以后才能访问该资源。

二、C++中使用互斥锁

在C++中,使用互斥锁(mutex)是一种常见的锁机制。互斥锁的主要作用就是在多个线程间同步对共享资源的访问。简单来说,加锁(lock)就是互斥锁对被保护的数据加上锁,而解锁(unlock)就是互斥锁把锁释放,使得其他线程可以访问该数据。

下面是一些示例代码,用于演示如何在C++中使用互斥锁:


#include <iostream>

#include <thread>

#include <mutex>

// 创建一个全局的互斥锁mutex

std::mutex g_mutex;

int g_count = 0;

void threadFunc()

{

   for (int i = 0; i < 1000; ++i)

   {

     // 申请互斥锁

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

     g_count++;

   }

}

int main()

{

   std::thread th1(threadFunc);

   std::thread th2(threadFunc);

   th1.join();

   th2.join();

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

   return 0;

}

上述代码中,我们首先定义了一个全局变量g_mutex,这是整个程序所使用的互斥锁。然后定义了一个全局变量g_count,这个变量是被线程修改的被保护数据。在主函数中,我们创建了两个线程th1和th2,它们都会调用线程函数threadFunc。在这个函数中,我们申请互斥锁g_mutex,并加上std::lock_guard,这样就可以保证在多个线程同时修改g_count时不会导致数据冲突。在两个线程完成以后,程序输出g_count的值。

三、使用条件变量

条件变量是互斥锁的常见配对,用来解决生产者-消费者模式,即一个线程等待其他一些线程满足一些条件以后才能进行操作。举个例子:如果一个线程在等待某个资源,但是另一个线程正在使用它,那么就需要通过条件变量来实现等待。条件变量的基本作用就是在满足某个条件之前把进程挂起。直到其它进程通知它该条件已经满足,进程才会重新恢复运行。

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


#include <iostream>

#include <thread>

#include <mutex>

#include <condition_variable>

std::mutex mtx;

std::condition_variable cv;

int g_count = 0;

bool g_ready = false;

void increment()

{

   while (true)

   {

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

     cv.wait(lock, [] return g_ready; );

     g_count++;

     g_ready = false;

     lock.unlock();

     cv.notify_all();

   }

}

void output()

{

   while (true)

   {

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

     g_ready = true;

     cv.notify_all();

     cv.wait(lock, [] return !g_ready; );

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

   }

}

int main()

{

   std::thread th1(increment);

   std::thread th2(output);

   th1.join();

   th2.join();

   return 0;

}

在这个示例代码中,我们定义了一个计数器g_count和一个条件变量g_ready,以及两个线程increment和output。在increment线程中,我们使用了std::unique_lock和std::condition_variable。这样,increment线程就能够等待g_ready变量变为true以后再继续执行。在output线程中,我们使用了g_ready变量和条件变量cv,用来通知increment线程计数器可以被更新了。

四、总结

本文介绍了使用互斥锁和条件变量来解决多线程编程中资源竞争问题的方法。通过学习这些基本的C++多线程编程技术,我们可以有效避免在多线程场景下的资源竞争问题,并实现更加高效和可靠的程序。当然,在实际开发过程中,我们也需要注意锁的使用和释放,以免死锁等问题的发生。

  
  

评论区

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