首页 > 编程语言 >C++ 创建一个线程

C++ 创建一个线程

时间:2024-11-16 15:20:17浏览次数:3  
标签:std thread 创建 C++ 线程 async include

        C++11 标准库引入了对多线程编程的支持,使得开发者能够以更加标准化的方式创建和管理线程。主要的线程管理方式是通过 std::thread 类,它可以用来创建、启动和管理线程。下面我将详细介绍如何使用 C++ 标准库创建线程的方法,以及其他一些相关的工具类和概念。

1. 使用 std::thread 创建线程

std::thread 是 C++ 标准库中用于创建和管理线程的类。可以用来启动独立线程来执行某些任务,任务可以是函数、成员函数或 lambda 表达式。

#include <thread>
#include <iostream>

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

int main() {
    // 创建一个线程执行函数
    std::thread t(threadFunction);
    // 等待线程结束
    t.join();  // join() 方法等待线程执行结束
    return 0;
}

在这个例子中:

  • 使用 std::thread t(threadFunction); 创建了一个新的线程来执行 threadFunction。
  • 线程对象 t 使用 join() 方法等待其完成,join() 会阻塞主线程,直到线程 t 结束。

线程分离 (detach)

可以选择使用 detach() 来将线程与主线程分离,从而使其在后台运行。分离的线程一旦开始执行,将无法再与主线程同步。

#include <thread>
#include <iostream>

void threadFunction()
{
    std::cout << "Detached thread is running." << std::endl;
}


int main() 
{
    std::thread t(threadFunction);
    t.detach();  // 分离线程,允许它在后台运行
    std::cout << "Main thread is ending." << std::endl;
    return 0;
}

使用 detach() 后,线程会在后台独立运行,主线程不会等待它结束,需要注意的是,分离线程在结束后主线程无法再管理其状态,因此需要确保线程资源能够得到妥善清理。

2. 使用 lambda 表达式创建线程

可以使用 lambda 表达式来创建线程,这样可以直接在线程内定义任务逻辑,非常灵活。

#include <thread>
#include <iostream>


int main() {
    // 使用 lambda 表达式创建线程
    std::thread t([] {
        std::cout << "Hello from lambda thread!" << std::endl;
    });

    t.join(); // 等待线程结束
    return 0;
}

在这个例子中,lambda 表达式被直接传递给 std::thread 的构造函数,创建了一个执行该 lambda 的线程。这种方式简洁易用,尤其适用于简单的任务。

3. 使用类的成员函数作为线程

std::thread 也可以用来执行类的成员函数,但是需要传递成员函数指针和对象实例来创建线程。

#include <thread>
#include <iostream>

class MyClass {
public:
    void memberFunction() {
        std::cout << "Hello from member function!" << std::endl;
    }
};


int main() {
    MyClass myObject;
    // 使用成员函数创建线程,需要传递对象实例
    std::thread t(&MyClass::memberFunction, &myObject);
    t.join(); // 等待线程结束
    return 0;
}

在这个例子中:

  • 使用 &MyClass::memberFunction 获取成员函数的指针,并使用 &myObject 传递对象实例,创建了一个执行成员函数的线程。
  • 注意成员函数需要通过对象实例来调用,因而需要传递对象的指针 &myObject。

4. 使用 std::async 创建任务

std::async 提供了另一种方式来启动并发任务,它返回一个 std::future,可以在未来获取线程任务的结果。

#include <future>
#include <iostream>

int threadFunction() {
    return 8888; // 线程的返回值
}

int main() 
{
    // 使用 std::async 创建并发任务
    std::future<int> result = std::async(std::launch::async, threadFunction);
    // 获取线程任务的返回值
    int value = result.get();
    std::cout << "Result from thread: " << value << std::endl;
    return 0;
}

在这个例子中:

  • 使用 std::async(std::launch::async, threadFunction) 来创建并启动一个并发任务。
  • std::future<int> 用于获取线程任务的结果,通过 result.get() 可以等待任务完成并获取返回值。

5. 传递参数给线程函数

std::thread 的构造函数支持传递参数,可以将参数传递给线程函数。参数可以是值类型、引用类型或者其他数据类型。

#include <thread>
#include <iostream>

void threadFunction(int value, const std::string &message) {
    std::cout << "Value: " << value << ", Message: " << message << std::endl;
}

int main() {
    int value = 42;
    std::string message = "Hello from thread";
    // 传递参数给线程
    std::thread t(threadFunction, value, std::ref(message));
    t.join(); // 等待线程结束
    return 0;
}

在这个例子中:

  • 线程函数 threadFunction 需要两个参数:一个整数和一个字符串。
  • 使用 std::ref(message) 传递引用参数,确保线程内对该参数的修改可以反映到主线程中。

6.总结

  • std::thread:是 C++ 标准库中创建线程的基础类,支持创建线程、传递参数、调用类成员函数等。
  • lambda 表达式:可以直接使用 lambda 表达式创建线程,非常方便灵活。
  • 传递参数:可以通过 std::thread 的构造函数向线程函数传递参数,包括值传递和引用传递。
  • 生命周期管理:创建线程后,需要使用 join() 或 detach() 管理线程的生命周期,否则程序可能会抛出异常。
  • std::async:提供了一种更高级的方式来启动并发任务,并通过 std::future 获取返回结果,适合需要获取任务结果的场景。

        std::thread 和 std::async 是 C++ 标准库提供的两种主要方式来创建和管理线程,std::thread 提供了更底层的控制,而 std::async 则提供了一种更高级、自动管理的方式。根据具体的需求和使用场景,可以灵活选择最合适的方式来实现多线程编程。

标签:std,thread,创建,C++,线程,async,include
From: https://blog.csdn.net/qq_27438159/article/details/143817414

相关文章

  • C++
    目录基础数据类型运算符流程控制函数指针与引用数组面相对象类的设计和对象的创建构造函数和析构函数常函数与常对象友元运算符重载封装(encapsulation)继承(inheritance)多态(polymorphism)结构体模板STL标准模板库容器算法迭代器基础进制注释:单行注释、多行注释数据类型标识符......
  • c++的static和extern
    首先这是一个static和extern的例子:#include<bits/stdc++.h>usingnamespacestd;inta(intb,intc){intd;d=rand()%3+1;externintd;return0;}intmain(){a(1,2);staticintd;cout<<d;return0;}实际上extern就是隐藏变......
  • 【C++类和对象基础篇下】再谈</|\>类和对象【完结撒花】
    --------------------------------------------------------------------------------------------------------------------------------- 每日鸡汤:再长的路,一步步也能走完,再短的路,不迈开双脚永远无法到达。你终会发现,拒绝放弃的那些努力,是多么值得!----------------------......
  • 小红书加微引导图生成器:轻松创建吸引人的微信号分享图
    大家好!今天我要向你们介绍一个超级实用的小工具——小红书加微引导图生成器。如果你经常在小红书上分享内容,想要吸引更多粉丝添加你的微信,这个工具绝对是你的得力助手!为什么需要这个工具?我们都知道,小红书对聊天中的文字审核非常严格。直接发送微信号可能会被系统拦截,影......
  • C/C++ 指针
    指针内存分类:运行内存存储命令注意当我们程序运行时系统会在运行内存中开启一片空间给当前程序使用32位机最多给一个程序开启4G的运行内存,64位8G将开启的内存以1字节为单位进行划分,每个字节的内存都有其对应的地址编号这些地址编号也是数据,其数据类型为指针......
  • cmake系列-怎么处理C++仅标头库
    这篇文章讲一下cmake怎么处理C++仅标头库,什么叫仅标头库呢,顾名思义,就是只有头文件的程序库。来看这么一个demo这个demo里面有demoA和demoB两个项目,其中demoA是一个仅标头库,demoB使用demoA提供的库。我们知道仅标头库是不能编译成程序目标的,当然用cmake处理也不可能违背......
  • JUC---多线程下的数据共享(基于ThreadLocal的思考)
    多线程下的数据共享(基于ThreadLocal的思考)起初实在写项目过程中,在完成超时订单自动取消的任务时,使用xxl-job,整个逻辑是需要从订单表中找出过期的订单,然后将其存入订单取消表。存入订单取消表时需要存储用户的信息。我最开始没想那么多,就直接从ThreadLocal中取出用户信息,但......
  • vivado 设计创建
    设计创建简介在规划器件I/O管脚,规划如何布局PCB以及决定Vivado®DesignSuite的使用模型后,就可以开始创建设计。设计创建包括:•规划设计的层级•确定设计中所需要的IP核并定制这些IP的配置•对于无法找到合适IP的......
  • 在 PowerShell 中,New-NetLbfoTeam 和 New-NetSwitchTeam 都用于创建网络适配器团队(Net
    在PowerShell中,New-NetLbfoTeam和New-NetSwitchTeam都用于创建网络适配器团队(NetworkAdapterTeaming),但它们针对的是不同的网络架构和技术。下面是这两个cmdlet的详细分析与区别,并以表格形式呈现。1. New-NetLbfoTeamNew-NetLbfoTeam是用于在本地计算机上配置网络......
  • c++的基础认识
    大家好!我是machenss,一个新兴CSDN作者,希望大家多多支持!从今天开始,我将给大家介绍一些简单的c++知识!首先,c++是一种编程语言,是c语言的升级版。学过其他编程语言的话(c.python.java等等),学习c++是很简单的。学习各种编程语言的第一步,当然是打印出“Helloworld!"啦!给大家看一下c++......