C++ 线程(串行 并行 同步 异步)详解

C++ 线程详解

C++ 中的线程是一种基于同步和异步的编程模型,可以帮助程序员更好地利用 CPU 和内存资源,提高程序性能。本篇文章将详细讲解C++ 线程的概念、分类以及用法。

线程概念

一个线程是程序执行中的单一线路,每个线程都有自己的指令计数器、栈空间和寄存器等,并同时访问共同的全局数据。C++ 中线程的作用和进程类似,一个进程包含多个线程,每个线程可以并发执行不同的操作,提高程序效率。

线程分类

串行线程

串行线程是指所有的线程按照固定的顺序依次执行,直到执行完成为止。它的执行流程如下:

#include <iostream>
#include <thread>
using namespace std;

void serial(int i)
{
    cout << "hello from serial thread " << i << endl;
}

int main()
{
    for (int i = 0; i < 5; ++i)
        serial(i);
    return 0;
}

输出结果为:

hello from serial thread 0
hello from serial thread 1
hello from serial thread 2
hello from serial thread 3
hello from serial thread 4

并行线程

并行是指多个线程同时执行不同的操作,可以提高多核 CPU 的使用效率。并行线程的执行顺序没有固定的先后顺序。例如,以下示例可以同时执行五个线程:

#include <iostream>
#include <thread>
using namespace std;

void parallel(int i)
{
    cout << "hello from parallel thread " << i << endl;
}

int main()
{
    thread t[5];
    for (int i = 0; i < 5; ++i)
        t[i] = thread(parallel, i);
    for (int i = 0; i < 5; ++i)
        t[i].join();
    return 0;
}

输出结果为:

hello from parallel thread 0
hello from parallel thread 2
hello from parallel thread 1
hello from parallel thread 4
hello from parallel thread 3

同步与异步

C++ 中细分为同步和异步两种线程。

同步线程是指程序在执行某个函数时会等待该函数执行完后才会往下执行,等待阻塞程序的状态,例如下面的示例:

#include <iostream>
#include <thread>
using namespace std;

void sync(int i)
{
    cout << "hello from sync thread " << i << endl;
}

int main()
{
    for (int i = 0; i < 5; ++i)
    {
        thread t(sync, i);
        t.join();
    }
    return 0;
}

输出结果为:

hello from sync thread 0
hello from sync thread 1
hello from sync thread 2
hello from sync thread 3
hello from sync thread 4

异步线程是程序执行某个函数时,不会等待出错继续执行下去,而该函数的执行到后台线程中,不影响程序的运行,例如下面的示例:

#include <iostream>
#include <future>
using namespace std;

int async()
{
    cout << "async thread running" << endl;
    return 100;
}

int main()
{
    future<int> async_result = async(launch::async, async);
    cout << "main thread running" << endl;

    int result = async_result.get();
    cout << "async thread finish with " << result << endl;
    return 0;
}

输出结果为:

async thread running
main thread running
async thread finish with 100

线程用法

C++ 中的线程主要有以下四个用法:

创建线程

C++ 中创建线程可以使用 std::thread 类,构造函数如下:

std::thread t(function, args);

其中 function 是需要在线程中执行的函数,args 是 function 函数参数。

以下示例创建了一个线程并执行其中的函数:

#include <iostream>
#include <thread>
using namespace std;

void foo()
{
    cout << "hello from thread" << endl;
}

int main()
{
    thread t(foo);
    t.join();
    return 0;
}

线程休眠

C++ 中可以使用 std::this_thread::sleep_for() 函数来使线程睡眠一定时间。

std::this_thread::sleep_for(std::chrono::milliseconds(time));

其中 time 是以毫秒为单位的时间。

以下示例让线程睡眠 1 秒:

#include <iostream>
#include <thread>
using namespace std;

void foo()
{
    this_thread::sleep_for(chrono::seconds(1));
    cout << "hello from thread" << endl;
}

int main()
{
    thread t(foo);
    t.join();
    return 0;
}

加锁

在并发中,多个线程同时访问共享资源会造成数据冲突,导致程序出错。加锁可以避免多个线程同时访问共享资源,而造成数据冲突。

C++ 中可以使用 std::mutex 实现加锁:

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;

mutex mx;

void foo()
{
    cout << "hello from thread " << this_thread::get_id() << endl;
    lock_guard<mutex> lock(mx);
    cout << "mutex is locked" << endl;
    //...
}

int main()
{
    thread t1(foo);
    thread t2(foo);

    t1.join();
    t2.join();
    return 0;
}

以上示例中,使用 lock_guard 对 mx 进行了加锁,保证对于 mx 对象的访问互斥进行。

线程池

线程池是管理线程的一种方式,可以允许在必要时重复使用工作线程,而不是在每次需要执行时都创建新的线程。线程池提供了将线程的创建、分配和销毁集中管理的能力。C++ 中提供了 std::async() 和 std::packaged_task 等用于管理线程池。

以下示例中是使用了 std::async() 启动异步任务:

#include <iostream>
#include <future>
using namespace std;

int async_task(int i)
{
    return i * 10;
}

int main()
{
    auto f1 = std::async(std::launch::async, async_task, 1);
    auto f2 = std::async(std::launch::async, async_task, 2);

    cout << f1.get() << endl;
    cout << f2.get() << endl;
    return 0;
}

其中 std::launch::async 参数表示该任务是异步执行的。

以上就是 C++ 中线程的串行、并行、同步和异步细分以及线程池的详细讲解,希望对大家有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ 线程(串行 并行 同步 异步)详解 - Python技术站

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

相关文章

  • Java 并发编程的可见性、有序性和原子性

    Java 并发编程的可见性、有序性和原子性是非常重要的概念和技能,在实际开发中必须掌握。本文将具体讲解这方面的知识。 可见性 所谓可见性,是指当多个线程同时访问共享变量时,一个线程修改了该变量的值,其他线程能够立即看到这个变化。在 Java 并发编程中,如果没有采取特殊的措施,共享变量的修改并不一定对所有线程都可见,这样就可能造成线程安全问题。 为了保证可见…

    多线程 2023年5月16日
    00
  • 浅谈Java的两种多线程实现方式

    浅谈Java的两种多线程实现方式 多线程是Java中非常重要的特性之一,它可以充分利用计算机的多核资源,在同一个应用程序中同时执行多个任务,提高程序的并发性和性能。Java在实现多线程方面提供了两种方式:继承Thread类和实现Runnable接口。以下分别进行详细讲解。 继承Thread类 继承Thread类是实现多线程的最简单方法,只需要继承Thread…

    多线程 2023年5月17日
    00
  • 简单对比C#程序中的单线程与多线程设计

    一、单线程设计 单线程指的是程序在运行时只有一个执行线程,所有的代码都在同一个线程中运行。在C#中,单线程设计常用于简单的小型程序或简单的任务,比如打印“Hello World”等。示例如下: using System; namespace ConsoleApplication { class Program { static void Main(strin…

    多线程 2023年5月17日
    00
  • JAVA多线程编程实例详解

    JAVA多线程编程实例详解 什么是多线程? 多线程指的是在一个程序中同时运行多个线程,也就是在同时处理多个任务。每个线程都有自己的计算机指令和数据,可以在同一个程序中独立运行而不影响其他线程。 为什么需要多线程? 多线程能够提高程序的效率和性能。当一个任务需要耗费大量时间时,使用多线程可以充分利用计算机的资源,将任务分解成多个子任务并同时执行,大大缩短处理时…

    多线程 2023年5月17日
    00
  • SpringBoot 并发登录人数控制的实现方法

    下面我来为你详细讲解“SpringBoot 并发登录人数控制的实现方法”的完整攻略。 1. 前言 在实际开发过程中,我们经常需要加入并发登录人数控制的功能。SpringBoot 作为目前最流行的 JavaWeb 框架之一,其内置的 Spring Security 在实现登录控制方面有很大的优势。同时,SpringBoot 还提供了一些自定义实现方式,用于满足…

    多线程 2023年5月16日
    00
  • Java多线程之ThreadLocal浅析

    Java多线程之ThreadLocal浅析 ThreadLocal 是 Java 中的一个用于多线程编程的类库,它提供了一个线程局部变量,每一个线程都有自己独立的副本,可以对该变量进行读写操作,而且互不影响,解决了多线程环境下共享数据的问题。 使用 ThreadLocal 先看下 ThreadLocal 的使用方式: public class ThreadL…

    多线程 2023年5月17日
    00
  • Python中多线程thread与threading的实现方法

    Python提供了两个模块来实现多线程,分别是thread和threading。其中,thread是低级模块,它提供了基本的线程功能。而threading是高级模块,它借鉴了Java中线程的概念,提供了更加高级、更加便捷的线程管理方式。下面分别介绍这两个模块的实现方法。 thread模块的实现方法 线程的创建 使用thread模块创建线程的方法很简单,只需要…

    多线程 2023年5月17日
    00
  • 使用p-limit 限制并发数源码解析

    下面我将详细讲解“使用p-limit限制并发数源码解析”的完整攻略。 什么是p-limit p-limit是一个Node.js模块,允许你封装一个异步函数,限制并发请求的最大数量。它遵循Promise接口,可以轻松地在Node.js和浏览器中使用。 安装p-limit 首先,我们需要使用npm来安装p-limit: npm install p-limit 安…

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