C++多线程编程:std::thread的用法

一、std::thread概述

std::thread是C++11提供的多线程库之一,它提供了一种方便的方式来并行执行代码,将多个任务同时执行。

std::thread库提供了创建线程、等待线程结束和管理线程的方法。在std::thread库中,我们可以使用std::thread对象的构造函数来创建一个新的线程,并告诉它应该执行哪个函数或lambda表达式。当执行完毕时,线程对象可以用join()或detach()方法来终止线程并等待它的结束。

void func1()
{
    // ...
}

int main()
{
    std::thread t(func1);
    // ...
    t.join();
    return 0;
}

在上面的代码中,我们定义了一个名为func1()的函数,并使用std::thread对象t在新线程中执行func1()函数。使用join()方法等待线程结束。在主线程中,我们可以执行其他操作,并在最后等待线程结束。

二、std::thread的创建和声明

std::thread对象的创建方式有多种方法,这里列举其中的两种方法。

第一种,使用函数指针创建线程:

// 一个简单的函数
void task1(int n)
{
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::cout << "task1: " << n << std::endl;
}

int main()
{
   std::thread t(task1, 1); // task1函数的参数是1
   std::cout << "main thread\n";
   t.join();
   return 0;
}

第二种,使用lambda表达式创建线程:

int main()
{
    std::thread t([](int n) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::cout << "task2: " << n << std::endl;
    }, 2);
    std::cout << "main thread\n";
    t.join();
    return 0;
}

注意:使用lambda表达式时,需要在参数列表中指定要传递给线程的值。

三、std::thread的数据共享和同步

多线程编程时,可能会遇到数据共享和同步的问题。对于数据共享的问题,很容易就会想到使用全局数据或静态数据。

// 全局变量
int g_count = 0;

void task1()
{
    for (int i = 0; i < 5; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        ++g_count;
    }
}

int main()
{
    std::thread t1(task1);
    std::thread t2(task1);

    t1.join();
    t2.join();

    std::cout << "g_count = " << g_count << std::endl;
    return 0;
}

然而,在多个线程中同时访问全局变量或静态变量时,可能会出现数据竞争。在上面的示例中,我们想要将g_count变量递增五次,但在实际执行过程中,可能出现每个线程各自的计数和。

因此,我们需要使用互斥量来同步访问。

std::mutex g_mutex;
int g_count = 0;

void task2()
{
    for (int i = 0; i < 5; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::lock_guard<std::mutex> lock(g_mutex);
        ++g_count;
    }
}

int main()
{
    std::thread t3(task2);
    std::thread t4(task2);

    t3.join();
    t4.join();

    std::cout << "g_count = " << g_count << std::endl;
    return 0;
}

在上面的示例中,我们使用了互斥量g_mutex,通过std::lock_guard<std::mutex> lock(g_mutex)来保护对g_count变量的访问。

四、std::thread的一些其他方法

std::thread还提供了一些其他方法来管理线程。

在主线程中,我们可以通过调用std::this_thread::get_id()来获取当前线程的id。

std::cout << "main thread id = " << std::this_thread::get_id() << std::endl;

在线程中,我们可以使用std::thread::yield()来暂停当前线程,允许其他线程执行。

void task3()
{
    for (int i = 0; i < 5; ++i) {
        std::this_thread::yield();
        std::cout << "task3\n";
    }
}

int main()
{
    std::thread t5(task3);

    for (int i = 0; i < 5; ++i) {
        std::cout << "main\n";
    }

    t5.join();
    return 0;
}

在上面的示例中,我们通过std::thread::yield()方法来将控制权交给其他线程,以便其他线程有机会执行。

std::thread还提供了detach()方法来在后台运行线程。

void task4()
{
    for (int i = 0; i < 5; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::cout << "task4: " << i << std::endl;
    }
}

int main()
{
    std::thread t6(task4);
    t6.detach();
    std::cout << "main thread\n";
    return 0;
}

在上面的示例中,我们使用detach()方法来后台运行线程t6,并且在主线程中继续执行其他操作。

五、std::thread的注意事项

在使用std::thread时,需要注意以下几点:

  • 使用std::this_thread::sleep_for()或std::this_thread::sleep_until()代替std::sleep()。
  • 不能将std::thread对象的拷贝赋值给其他变量或传递给函数。
  • std::thread应该在函数结束前被join()或detach()。
  • 对于临界区的访问,应该使用std::lock_guard<std::mutex>或std::unique_lock<std::mutex>。

六、总结

本文介绍了std::thread库的一些基本用法,包括声明和创建线程、线程的数据共享和同步、std::thread的一些其他方法以及注意事项。在多线程编程时,需要特别注意线程安全和数据同步,避免出现数据竞争等问题。

原创文章,作者:RVUP,如若转载,请注明出处:https://www.506064.com/n/133532.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
RVUPRVUP
上一篇 2024-10-03 23:59
下一篇 2024-10-03 23:59

相关推荐

  • Python多线程读取数据

    本文将详细介绍多线程读取数据在Python中的实现方法以及相关知识点。 一、线程和多线程 线程是操作系统调度的最小单位。单线程程序只有一个线程,按照程序从上到下的顺序逐行执行。而多…

    编程 2025-04-29
  • Java Thread.start() 执行几次的相关问题

    Java多线程编程作为Java开发中的重要内容,自然会有很多相关问题。在本篇文章中,我们将以Java Thread.start() 执行几次为中心,为您介绍这方面的问题及其解决方案…

    编程 2025-04-29
  • 多线程和多进程的应用

    多线程和多进程是现代编程中常用的技术,可以提高程序的效率和性能。本文将从不同的角度对多线程和多进程进行详细的介绍和应用。 一、多线程 vs 多进程 多线程和多进程都是为了实现程序并…

    编程 2025-04-27
  • Python多线程模块实践

    本文将向大家介绍Python中的多线程模块,并通过示例代码来展示如何灵活使用线程提升程序的性能。同时,本文还将讨论Python多线程模块使用中可能遇到的一些问题及其解决方法。 一、…

    编程 2025-04-27
  • 用c++实现信号量操作,让你的多线程程序轻松实现同步

    在多线程编程中,线程之间的同步问题是非常重要的。信号量是一种解决线程同步问题的有效机制。本文将介绍如何使用C++实现信号量操作,让你的多线程程序轻松实现同步。在介绍实现方法之前,我…

    编程 2025-04-25
  • 多线程编程中的pthread_create函数详解

    一、概述 在多线程编程中,pthread_create是一个十分重要的函数,它用于创建一个新的线程,并在新线程中执行一个用户指定的函数。本篇文章将从以下几个方面对pthread_c…

    编程 2025-04-24
  • NSOperation:iOS多线程编程的不二选择

    一、什么是NSOperation? NSOperation是在iOS开发中用于管理多线程编程的类,它是一套基于GCD(Grand Central Dispatch)的高层抽象。NS…

    编程 2025-04-12
  • matlab std详解

    一、简介 Matlab是一种强大的计算机程序,可以用来进行数值分析和计算,它可以帮助您完成许多其他编程语言所无法实现的任务。Matlab STD则是一种常用的Matlab工具箱,它…

    编程 2025-03-12
  • 深入了解 Swift 多线程

    一、基本概念 Swift 作为一门面向对象编程语言,自然也支持多线程编程。在 Swift 中,我们可以使用 GCD (Grand Central Dispatch)、NSOpera…

    编程 2025-02-25
  • 多线程事务控制

    一、基本概念 事务是指作为单一逻辑工作单元执行的一系列操作。多线程事务控制就是在多线程并发环境下对事务进行管理和控制,保证事务的原子性、一致性、隔离性和持久性。 原子性是指事务中的…

    编程 2025-02-24

发表回复

登录后才能评论