C++11 并发指南之std::thread 详解

C++11 并发指南之std::thread 详解

什么是std::thread?

std::thread是C++11提供的用于实现线程的类,它对操作系统的线程进行了封装,提供了一种较为方便、直观的方式来创建、管理和使用多线程程序。

std::thread的使用方法

std::thread的使用需要包含头文件,其构造函数可以接受可调用对象(函数、函数指针、lambda表达式等),并创建一个新的线程来执行该可调用对象中的内容。下面是一个创建并启动一个新线程的简单示例:

#include <iostream>
#include <thread>
void func(int x)
{
    std::cout << "The parameter passed in is: " << x << std::endl;
}
int main()
{
    std::thread t(func, 100);
    t.join();//等待子线程完成后再退出主线程
    return 0;
}

在上面的示例中,我们通过std::thread的构造函数创建了一个新线程t,并向其中传递了参数100。在新线程中执行的是函数func,该函数打印了参数x的值。由于在主线程中创建的t线程会成为一个独立的线程,因此该程序的输出有可能是乱序的。

同时,我们在主线程中调用了t.join(),该函数会等待线程t的完成后再返回,保证了该程序能够正确的输出结果。

std::thread的其他使用方法

线程的启动方式

std::thread的构造函数提供多种方式来创建线程,最常用的是传递函数指针,但是除此之外,还可以用lambda表达式、std::bind和std::function等方式来创建线程。

以下是使用lambda表达式的示例:

std::thread t([](int x) {std::cout << "Thread running, parameter passed in is: " << x << std::endl;}, 100);

以下是使用std::bind的示例:

void func(int x, const std::string& str)
{
    std::cout << str << " The parameter passed in is: " << x << std::endl;
}
int main()
{
    std::string str = "Thread running:";
    std::thread t(std::bind(func, 100, str));
    t.join();
    return 0;
}

线程的结束和退出

std::thread的对象有三种状态:

1.默认构造,即对象未与任何线程相关联。

2.与线程相关联,并处于运行状态。

3.与线程相关联,并处于非运行状态(已经执行完毕,或者尚未运行)。

线程结束后,可以调用join或detach来加以处理。

join的作用是等待线程结束后,将线程与主线程的执行流程合并,从而使主线程等待线程结束后再执行下面的操作。以下是join的简单示例:

std::thread t(func);
t.join();//等待线程运行结束后再执行接下来的代码

detach的作用是将线程与主线程分离,即使主线程退出,线程仍可以继续运行。使用detach时要特别注意线程的状态,如果线程已经处于非运行状态,会抛出std::system_error异常。以下是detach的示例:

std::thread t(func);
t.detach();//将线程与主线程分离

线程的管理

std::thread提供了一些成员函数来获取线程的ID、判断线程是否可用、判断线程是否已经执行完成等。

以下是获取线程ID的示例:

std::thread::id id = t.get_id();//获取t线程的ID
std::cout << "Thread id: " << id << std::endl;

以下是判断线程是否可用的示例:

if (t.joinable())//判断t线程是否joinable
{
    t.join();
}

示例分析

示例1:

#include <iostream>
#include <thread>
#include <chrono>
void func()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));//让线程休眠1秒
    std::cout << "Thread running..." << std::endl;
}
int main()
{
    std::cout << "Main thread running..." << std::endl;
    std::thread t(func);
    t.detach();
    if (t.joinable())
    {
        t.join();//如果t线程能够被join,会抛出异常
    }
    std::cout << "Main thread exiting..." << std::endl;
    return 0;
}

在这个示例中,我们创建了一个子线程t,使其执行函数func,然后将线程t与主线程分离(调用t.detach())。在主线程中,我们并没有调用t.join(),因此该程序的输出可能是乱序的,主线程和子线程的执行没有关联。

接着,我们判断了一下线程t是否可用,如果可用,就调用t.join()等待线程t的结束。由于线程t已经被分离,因此判断之后会抛出std::system_error异常。

最后输出了“Main thread exiting...”,主线程可以正常结束。

示例2:

#include <iostream>
#include <thread>
void func(int& x)
{
    x++;
}
int main()
{
    int x = 0;
    std::thread t(func, std::ref(x));//需要使用std::ref函数对x进行引用包装
    t.join();
    std::cout << "x increment by thread: " << x << std::endl;
    return 0;
}

这个示例中,我们创建了一个子线程t,使其执行函数func,并将x的引用传递给该线程。为了正确地传递x,我们使用了std::ref函数对x进行了引用包装。

在函数func中,我们对x进行了递增操作x++,然后线程t运行结束。在主线程中,我们输出了x的值,可以看到子线程确实对x进行了递增操作。

总结

本文主要介绍了std::thread的使用方法、启动方式、线程的结束和退出以及线程的管理等方面,同时给出了两个简单的示例。

std::thread在C++11中提供了一种便捷的方式来实现多线程,相比于传统的操作系统API,std::thread的使用更加方便直观,能够提高多线程编程的效率。

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

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

相关文章

  • Python使用asyncio包处理并发详解

    当今网络服务越来越注重并发访问的处理,常见的异步框架有 gevent, twisted, tornado等,而作为一个优秀的异步框架,Python的asyncio更是备受关注。Asyncio 是 Python 3.4 新增的异步IO模块,它提供了基于协程的异步编程方式,使得异步编程更加易用、高效、可控。 下面我们来详细介绍Python中使用asyncio包进…

    多线程 2023年5月17日
    00
  • Python多线程编程(二):启动线程的两种方法

    文章标题:Python多线程编程(二):启动线程的两种方法 前言 编写多线程程序可以在某种程度上提高程序的并发性和性能,Python提供了多种方式支持多线程编程。本文将着重讲解启动线程的两种方法:继承threading.Thread类和使用函数式API:threading.Thread。 使用继承方式实现启动线程 创建线程方式中,最常见的方法就是继承Thre…

    多线程 2023年5月17日
    00
  • JUC并发编程LinkedBlockingQueue队列深入分析源码

    JUC并发编程LinkedBlockingQueue队列深入分析源码 1. LinkedBlockingQueue简介 LinkedBlockingQueue是Java集合框架中的一种队列,它实现了BlockingQueue接口,并且是线程安全的,支持高效并发读写操作。LinkedBlockingQueue是一种无界队列,因此队列中的元素数量可以无限增长,不…

    多线程 2023年5月17日
    00
  • java多线程编程实例

    Java多线程编程实例攻略 Java多线程编程使得程序可以同时运行多个任务,从而提高程序的效率,降低资源的浪费。本篇攻略将介绍Java多线程编程的基本概念、实例说明和注意事项。 多线程编程的基本概念 进程(process):计算机中一个正在运行程序的实例。 线程(thread):进程中负责执行任务的单个执行流程。每个进程可以拥有多个线程。 并发:多个任务同时…

    多线程 2023年5月17日
    00
  • 深入理解 Java、Kotlin、Go 的线程和协程

    深入理解 Java、Kotlin、Go 的线程和协程攻略 前言 线程和协程是现代编程中最为重要的并发编程方式之一。Java、Kotlin 和 Go 都是常用的编程语言。本文将围绕这几门语言的线程和协程进行分析和比较,助您深入理解它们的本质和局限。 线程和协程的基本概念 线程 线程是操作系统中独立的执行单元。多线程可以提高程序的效率,使程序可以同时完成多个任务…

    多线程 2023年5月17日
    00
  • HTML5之多线程(Web Worker)

    HTML5的一个重要特性是支持多线程(Web Worker),这使得在浏览器执行JavaScript代码时可以使用多个线程加快程序运行速度,提升用户体验。 前置知识 在介绍Web Worker之前,需要先了解下JavaScript中的单线程和异步编程。JavaScript运行在浏览器端时只有一个主线程,在这个主线程中执行各种操作,包括用户交互和执行代码等等,…

    多线程 2023年5月17日
    00
  • 谈谈java的concurrent用法

    Java Concurrent 包使用攻略 Java Concurrent 包提供了一系列并发编程的工具类和接口,用于简化多线程编程、提高并发性能和优化资源利用。在编写高性能的、并发的、安全的多线程应用程序时,Java Concurrent 包是一项必不可少的技术。本文将详细介绍 Java Concurrent 包的常用用法。 基础概念 线程安全性 多线程并…

    多线程 2023年5月16日
    00
  • 彻底搞懂Java多线程(一)

    彻底搞懂Java多线程(一) 为什么需要多线程 在Java应用程序中,多线程可以帮助我们利用CPU资源,提高程序的执行效率,加速程序的运行速度。理论上,一个程序的执行速度可以比单线程的程序快1到100倍不等。 Java多线程的实现方式 Java多线程的实现方式主要有两种:继承Thread类和实现Runnable接口。 继承Thread类 使用继承Thread…

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