C++线程之thread详解

C++线程之thread详解

简介

线程是现代程序设计中最重要和有用的概念之一,是使程序在同时执行多个任务的机制。C++语言提供了标准库中的thread类,使得在C++中创建线程非常简单。本文将对thread的用法进行详细的讲解和说明,包括如何创建和管理线程、如何进行线程同步等内容。

创建线程

C++线程库提供了std::thread类用于创建和管理线程。创建线程的最基本方式是提供一个函数,并将其作为参数传递给std::thread构造函数。例如,下面的代码中,我们创建了一个只输出一句话的线程:

#include <iostream>
#include <thread>

void my_thread_function(){
    std::cout << "Hello from my thread!" << std::endl;
}

int main(){
    std::thread my_thread(my_thread_function);
    my_thread.join();
    return 0;
}

在上面的代码中,我们创建了一个名为my_thread_function的函数,并将其作为参数传递给了std::thread类的构造函数。然后,我们通过调用join等待线程执行完毕,然后退出程序。运行上述代码,输出结果为:

Hello from my thread!

可以看到线程已经成功地执行了,输出了我们期望的结果。当std::thread对象被销毁时,它会自动调用join方法等待线程执行完成。

线程同步

多线程应用程序中,同步是一个非常重要的问题。如果没有有效的同步,可能会出现数据竞争、死锁等问题。C++线程库为我们提供了一些同步机制,例如互斥锁和条件变量。

互斥锁

互斥锁是一种同步机制,常用于保护临界区代码,以确保同一时间只有一个线程可以访问该代码块。C++线程库中提供了std::mutex类用于实现互斥锁。

下面的示例代码中,我们通过定义互斥锁来保护global_variable变量的访问。

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

std::mutex my_mutex;
int global_variable = 0;

void my_thread_function(){
    for(int i = 0; i < 10; ++i){
        my_mutex.lock();
        ++global_variable;
        my_mutex.unlock();
    }
}

int main(){
    std::thread my_thread1(my_thread_function);
    std::thread my_thread2(my_thread_function);

    my_thread1.join();
    my_thread2.join();

    std::cout << "global_variable is " << global_variable << std::endl;

    return 0;
}

在上面的代码中,我们创建了两个线程,两个线程都会对global_variable变量进行操作,因此,我们需要对它进行保护。我们使用std::mutex类来定义互斥锁,并在操作之前调用lock方法来获取锁,操作完成后调用unlock方法释放锁。运行上述代码,输出结果为:

global_variable is 20

可以看到,最终global_variable的值为20,证明了两个线程都可以正确地访问并更新该变量。

条件变量

条件变量是一种同步机制,允许线程等待特定条件的满足。C++线程库中提供了std::condition_variable类用于实现条件变量。

下面的示例代码中,我们使用std::condition_variable来实现一个简单的生产者-消费者模型。

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

std::queue<int> my_queue;
std::mutex my_mutex;
std::condition_variable my_cv;

void producer_thread_function(){
    for(int i = 0; i < 10; ++i){
        std::unique_lock<std::mutex> lock(my_mutex);
        my_queue.push(i);
        lock.unlock();
        my_cv.notify_one();
    }
}

void consumer_thread_function(){
    while(true){
        std::unique_lock<std::mutex> lock(my_mutex);
        my_cv.wait(lock, []{ return !my_queue.empty(); });
        int data = my_queue.front();       
        my_queue.pop();
        lock.unlock();
        std::cout << "Consumed: " << data << std::endl;
        if(data == 9) break;
    }
}

int main(){
    std::thread producer_thread(producer_thread_function);
    std::thread consumer_thread(consumer_thread_function);

    producer_thread.join();
    consumer_thread.join();

    return 0;
}

在上面的代码中,我们创建了两个线程,producer_thread_function线程负责生产数据,consumer_thread_function线程负责消费数据。我们使用std::queue保存数据,并与std::mutexstd::condition_variable一起使用,以实现线程的同步和等待。

具体来说,我们在生产者线程中使用unique_lock获取锁,并使用my_cv.notify_one()通知消费者线程有新的数据需要消费。在消费者线程中,我们首先使用my_cv.wait()方法来等待有新的数据可以消费。同时,我们定义了一个lambda表达式作为wait方法的第二个参数,以在等待期间检查队列是否为空。当wait方法返回后,我们使用my_queue.pop()将数据从队列中消费,并使用lock.unlock()释放锁。

运行上述代码,输出结果为:

Consumed: 0
Consumed: 1
Consumed: 2
Consumed: 3
Consumed: 4
Consumed: 5
Consumed: 6
Consumed: 7
Consumed: 8
Consumed: 9

可以看到,数据正确地被生产和消费,证明了我们实现了一个简单的生产者-消费者模型。

结论

以上是对C++线程库中std::thread类的详细介绍和说明。通过本文,我们可以了解到如何使用std::thread类创建和管理线程、如何使用互斥锁和条件变量进行线程同步等内容。希望读者可以通过本文对C++多线程编程有更深入的了解和认识。

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

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

相关文章

  • 如何最大限度地降低多线程C#代码的复杂性

    如何最大限度地降低多线程C#代码的复杂性?下文将介绍三个主要的攻略。 1. 使用异步编程 使用异步编程是降低代码复杂性的一个非常重要的方法。尤其是在处理长时间运行的操作时,可以使用异步编程来避免阻塞主线程,同时可以提高程序的响应速度,让我们的程序更加高效。在使用异步编程时,我们需要使用 async 和 await 关键字。 以下代码演示了如何在不堵塞主线程的…

    多线程 2023年5月16日
    00
  • 详解PHP服务器如何在有限的资源里最大提升并发能力

    当PHP服务器面对大量用户请求时,如何在有限的资源里提升其并发能力是一个非常关键的问题。下面是一些具体做法以及案例分析,可以帮助提升PHP服务器的并发能力。 1. 改善代码架构 优化代码架构可以有效提高服务器的性能。具体而言,可以针对如下几个方面进行优化。 1.1 精简代码 减少无用的代码和逻辑,缩小代码体积,可以有效减少服务器的负担,提高响应速度。比如,可…

    多线程 2023年5月16日
    00
  • 基于rocketmq的有序消费模式和并发消费模式的区别说明

    基于RocketMQ的有序消费模式和并发消费模式的区别说明 1. 有序消费模式 在有序消费模式下,消息消费是按照消息的发送顺序依次进行的。具体实现方式是,消息生产者将消息发送到同一个Message Queue中,而Message Queue按照顺序将消息发送给Consumer进行消费。因此,在有序消费模式下,同一个Message Queue的消息一定会按照发…

    多线程 2023年5月17日
    00
  • 浅谈Nginx10m+高并发内核优化详解

    浅谈Nginx10m+高并发内核优化详解 Nginx 10m+高并发场景分析 Nginx是一个高性能、高并发的Web服务器,广泛应用于互联网企业和大型网站等高并发场景。在高并发的场景下,Nginx的性能极为重要,如何优化Nginx的性能成为了Web开发人员必须掌握的技能。下面我们就来分析一下Nginx在10m+高并发场景下的性能瓶颈和优化方案。 性能瓶颈分析…

    多线程 2023年5月16日
    00
  • java多线程CyclicBarrier的使用案例,让线程起步走

    下面开始为大家详细讲解Java多线程CyclicBarrier的使用案例。 什么是CyclicBarrier? CyclicBarrier是Java多线程中的一个构造器,它可以协调多线程间的运行,实现多个线程阻塞至某个状态之后再全部同时执行。可以说CyclicBarrier是控制多线程执行时序的一种工具。 CyclicBarrier的使用场景 CyclicB…

    多线程 2023年5月17日
    00
  • Java多线程之并发编程的基石CAS机制详解

    Java多线程之并发编程的基石CAS机制详解 什么是CAS CAS,即Compare And Swap,中文翻译为比较并交换。是一种无锁算法,用于实现多线程同步。在CAS操作中包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在CA…

    多线程 2023年5月16日
    00
  • python多线程互斥锁与死锁

    下面是关于“python多线程互斥锁与死锁”的详细讲解。 什么是互斥锁 在多线程编程中,如果多个线程同时对共享资源进行读写操作,可能会导致数据出现混乱或不一致的情况。为了解决这个问题,我们需要使用互斥锁(Mutex)来保证同一时刻只有一个线程访问共享资源。 互斥锁可以分为两种类型:临界区互斥锁和条件变量互斥锁。 临界区互斥锁:在程序中使用一个互斥锁对象来保护…

    多线程 2023年5月16日
    00
  • 分享Java多线程实现的四种方式

    让我来为您详细讲解“分享Java多线程实现的四种方式”的完整攻略。 1. 使用继承Thread类方式实现多线程 这种方式是通过继承Thread类并重写它的run()方法来实现多线程。示例如下: public class MyThread extends Thread { @Override public void run() { // 线程要执行的代码 } …

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