C++11学习之多线程的支持详解

C++11学习之多线程的支持详解

在C++11标准中,多线程支持成为了一个正式的标准库,并引入了一些新的概念和类型,如线程、互斥锁、条件变量等,以及一些用于控制线程行为的函数和类。

下面我们来详细讲解多线程的支持。

线程

在线程头文件<thread>中定义了线程类std::thread,用于创建和控制线程。线程类的构造函数接收一个可调用对象,并执行它。例如,下面的代码创建了一个线程,并使用lambda函数作为可调用对象:

#include <iostream>
#include <thread>

void foo() {
  std::cout << "Hello, World!" << std::endl;
}

int main() {
  std::thread t(foo);

  t.join(); // 等待线程 t 执行完毕

  return 0;
}

上面的代码中,std::thread t(foo)创建一个新的线程,并执行 foo()函数。线程执行完毕后,必须调用join()函数才能等待并回收线程资源。

线程类还提供了一些其他的创建线程的方式,如:

std::thread t1;
t1 = std::thread(foo);       // 拷贝构造函数
std::thread t2(foo);         // 直接构造函数
std::thread t3(&foo);        // 函数指针作为可调用对象
std::thread t4([]{ foo(); }); // lambda函数作为可调用对象

互斥锁

互斥锁是用于控制对共享资源的访问的一种机制。在C++11标准中,定义了std::mutex类型,用于实现互斥锁。

互斥锁的使用分为两个步骤:上锁和解锁。当一个线程对共享资源进行访问时,需要先上锁,以防止其他线程同时对同一共享资源进行操作。操作结束后,需要解锁以释放互斥锁,使得其他线程可以对共享资源进行操作。

#include <iostream>
#include <thread>
#include <mutex>

int counter = 0;
std::mutex mtx;

void increment() {
  for (int i = 0; i < 10000; ++i) {
    std::lock_guard<std::mutex> lock(mtx);
    ++counter;
  }
}

int main() {
  // 创建两个线程对counter进行操作
  std::thread t1(increment);
  std::thread t2(increment);

  // 等待两个线程执行完毕
  t1.join();
  t2.join();

  std::cout << "Counter = " << counter << std::endl;

  return 0;
}

上面的代码中,我们使用互斥锁保证了counter变量的线程安全。在increment()函数中,我们使用了std::lock_guard<std::mutex>类,它会自动在构造函数中上锁,在析构函数中解锁。

注意:当调用的函数可能抛出异常时,需要使用std::unique_lock类手动上锁和解锁。

条件变量

条件变量是一种用于线程间通信的机制。在C++11标准中,条件变量有std::condition_variablestd::condition_variable_any两种类型。

我们使用条件变量来实现一个生产者消费者模型:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>

std::queue<int> q;
std::mutex mtx;
std::condition_variable cv;

void producer() {
    for (int i = 0; i < 10; i++) {
        std::unique_lock<std::mutex> lock(mtx);
        q.push(i);
        lock.unlock();
        cv.notify_one();
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟生产者生产速度
    }
}


void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [] { return !q.empty(); });
        auto item = q.front();
        q.pop();
        lock.unlock();
        std::cout << "Consumer " << std::this_thread::get_id() << " consumed " << item << std::endl;
    }
}

int main() {
    std::thread producer_thread(producer);
    std::thread consumer_thread(consumer);
    consumer_thread.join();
    producer_thread.join();

    return 0;
}

上面的代码中,生产者线程和消费者线程共享队列q,并且使用互斥锁和条件变量来保证线程安全和正确的顺序。

生产者线程在生产一个item之后,将其压入队列q,并通过cv.notify_one()通知消费者线程可以消费了,然后等待一段时间继续生产。消费者线程在等待队列不为空时,从队列头部取出一个item,输出它,并继续等待下一个item。

总结

本文讲解了C++11标准中多线程的支持,涉及线程、互斥锁、条件变量等多个方面。对于初学者来说,理解这些概念并熟练掌握它们的使用可以使你写出更安全、更高效、更复杂的多线程程序。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++11学习之多线程的支持详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • 详解java解决分布式环境中高并发环境下数据插入重复问题

    详解 Java 解决分布式环境中高并发环境下数据插入重复问题 背景 在高并发环境下,数据插入操作很容易出现重复插入的问题。例如,多个用户同时提交一个相同的表单,系统可能会将同样的数据插入数据库中多次,造成数据不一致的问题。这种情况在分布式环境下尤其常见,因为不同节点的时间戳可能不一致。 解决方案 方法一:利用 Unique 约束 在数据库中设置 Unique…

    多线程 2023年5月16日
    00
  • 详细分析Java并发集合ArrayBlockingQueue的用法

    下面是详细的攻略: Java并发集合ArrayBlockingQueue的用法分析 1. 简介 ArrayBlockingQueue是Java中的一个并发集合,是线程安全的,可以在生产者和消费者之间传递数据。它是一个有界队列,具有固定的大小,即在构造时指定队列的容量。 2. 常用方法 ArrayBlockingQueue有许多常用的方法,下面是其中的一些: …

    多线程 2023年5月16日
    00
  • golang并发编程的实现

    Golang并发编程的实现完整攻略 Golang是一门强大的并发编程语言,提供了一系列的并发编程工具来帮助我们更容易地进行并发编程。在本文中,我们将介绍Golang并发编程的基础知识,以及如何使用Golang的goroutine、channel和select语句来实现并发编程。 并发编程基础 并发编程是指同时执行多个任务的编程方式。Golang提供了goro…

    多线程 2023年5月17日
    00
  • Java并发程序刺客之假共享的原理及复现

    Java并发程序刺客之假共享 1. 假共享的概念 假共享(False sharing)是指多个线程访问共享内存中不同的变量,但它们彼此之间共享了同一个缓存行(cache line),这样就会频繁地触发缓存一致性协议,导致性能下降。 缓存一致性协议(Coherence protocol)是指在多个处理器/核心之间共享缓存的时候保持数据一致的一种协议。常见的协议…

    多线程 2023年5月16日
    00
  • C++ 多线程编程建议之 C++ 对多线程/并发的支持(下)

    下面是关于“C++ 多线程编程建议之 C++ 对多线程/并发的支持(下)”的完整攻略。 什么是 C++ 对多线程/并发的支持 C++11 引入了对多线程/并发的支持,使得 C++ 语言能够更好地应对多线程程序的开发和实现。这些支持主要包括以下内容: std::thread 类型:C++11 引入了 std::thread 类型,它代表了一个执行线程,可以运行…

    多线程 2023年5月17日
    00
  • php使用curl并发减少后端访问时间的方法分析

    PHP使用cURL并发技术实现优化后端访问时间 在高并发的web应用中,后端向多个不同的目标执行HTTP请求是很常见的,并发执行这些请求是可以显著提高应用性能的。cURL库是PHP中强大而常用的HTTP客户端库之一,本文将介绍如何使用cURL的并发技术来减少后端访问时间。 什么是cURL并发技术? cURL并发技术是一种将多个HTTP请求同时发送到后端,并在…

    多线程 2023年5月16日
    00
  • Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解

    下面是针对“Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解”的完整攻略。 什么是生产者消费者模式? 生产者消费者模式是指:生产者生产出来的任务放到一个仓库中,消费者从仓库中取出任务来消费。这样就将生产者和消费者融为一体,实现了解耦和。 生产者消费者模式需要解决的问题是:当仓库中的任务被消费完了,如何实现等待生产者生产新任务,同时也不影响已经在…

    多线程 2023年5月16日
    00
  • Java中对于并发问题的处理思路分享

    Java中对于并发问题的处理思路分享 多线程编程 在Java中,实现多线程编程主要通过 Thread 类或者实现 Runnable 接口来完成。创建和启动线程的方式有两种: 继承 Thread 类 class MyThread extends Thread { @Override public void run() { // 线程执行逻辑 } } MyThr…

    多线程 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部