首页 > 编程语言 >C++之线程管控(二)

C++之线程管控(二)

时间:2023-07-08 11:22:05浏览次数:40  
标签:std 管控 thread C++ 线程 print include 函数

背景

随着多核处理器的普及,多线程编程已经成为软件开发中不可或缺的一部分。C++11标准为我们带来了线程库,让我们能够更方便地在C++中实现多线程编程。在这篇博客中,我们将介绍C++线程管控的基本概念和方法,包括向线程函数传递参数,移交线程归属权,运行时选择线程数量和识别线程。

向线程函数传递参数

在C++中,我们可以使用std::thread类来创建线程。当我们创建一个线程时,可以将函数作为参数传递给线程构造函数。此外,我们还可以向这个函数传递参数。这里有一个简单的例子:

#include <iostream>
#include <thread>

void print_sum(int a, int b) {
    std::cout << "Sum: " << a + b << std::endl;
}

int main() {
    std::thread t(print_sum, 3, 4);
    t.join();
    return 0;
}

在这个例子中,我们创建了一个名为print_sum的函数,它接受两个整数参数并打印它们的和。然后,我们创建了一个线程t,并将print_sum函数作为参数传递给线程构造函数,同时传递了两个整数参数3和4。最后,我们调用join()函数等待线程执行完成。

移交线程归属权

在C++中,线程对象是可移动的,但不可复制的。这意味着我们可以将一个线程对象的归属权转移给另一个线程对象,但不能创建一个线程对象的副本。这可以通过使用std::move()函数实现。下面是一个例子:

#include <iostream>
#include <thread>

void print_hello() {
    std::cout << "Hello, World!" << std::endl;
}

int main() {
    std::thread t1(print_hello);
    std::thread t2 = std::move(t1);
    t2.join();
    return 0;
}

在这个例子中,我们创建了一个名为print_hello的函数,它不接受任何参数并打印Hello, World!。然后,我们创建了一个线程t1,并将print_hello函数作为参数传递给线程构造函数。接下来,我们将t1的归属权转移到t2,并调用join()函数等待线程执行完成。

在运行时选择线程数量

有时,我们希望根据程序运行时的环境来选择线程的数量。例如,我们可能希望根据计算机上可用的处理器数量来创建线程。我们可以使用std::thread::hardware_concurrency()函数来查询可用的处理器数量。下面是一个例子:

#include <iostream>
#include <thread>
#include <vector>

void print_hello() {
    std::cout << "Hello, World!" << std::endl;
}

int main() {
    unsigned int num_threads = std::thread::hardware_concurrency();
    std::vector<std::thread> threads;

    for (unsigned int i = 0; i < num_threads; ++i) {
        threads.push_back(std::thread(print_hello));
    }

    for (auto& t : threads) {
        t.join();
    }

    return 0;
}

在这个例子中,我们首先查询可用的处理器数量,然后创建一个线程向量。接下来,我们根据处理器数量创建线程,并将它们添加到线程向量中。最后,我们遍历线程向量,调用join()函数等待所有线程执行完成。

识别线程

在多线程编程中,有时我们需要识别正在执行的线程。C++标准库提供了std::this_thread命名空间,其中包含一些有用的函数,如get_id(),用于获取当前线程的唯一标识符。下面是一个例子:

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

std::mutex mtx;

void print_thread_id() {
    std::unique_lock<std::mutex> lock(mtx);
    std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;
    lock.unlock();
}

int main() {
    std::vector<std::thread> threads;

    for (int i = 0; i < 5; ++i) {
        threads.push_back(std::thread(print_thread_id));
    }

    for (auto& t : threads) {
        t.join();
    }

    return 0;
}

在这个例子中,我们创建了一个名为print_thread_id的函数,它使用std::this_thread::get_id()函数获取当前线程的ID,并打印它。我们还使用了std::mutex和std::unique_lock来确保输出不会发生冲突。然后,我们创建了一个线程向量,并创建了5个线程,将它们添加到线程向量中。最后,我们遍历线程向量,调用join()函数等待所有线程执行完成。

最后

总结一下,在这篇博客中,我们介绍了C++线程管控的基本概念和方法,包括向线程函数传递参数,移交线程归属权,运行时选择线程数量和识别线程。C++11标准库中的线程支持为我们提供了强大的多线程编程能力。通过熟练掌握这些概念和方法,我们可以更好地利用多核处理器,提高程序的性能和响应速度。

 

标签:std,管控,thread,C++,线程,print,include,函数
From: https://www.cnblogs.com/blizzard8204/p/17536951.html

相关文章

  • Java和线程的一些讨论
    Java语言及Java的多线程机制,其中:第一部分是对Java简介,包括Java产生的背景和经过、Java的特点和应用方向、Java发展趋势.第二部分介绍面向对象的Java编程方法、及与C++语言作了一些比较.包括如何编写JavaApolet、在Applet中如何实现各种常用对象、以及使用Java实现高级编程(......
  • C++ Primer 学习笔记——第七章
    第七章类前言基本数据类型有时候并不能解决某些特定问题,而通过自定义的类就可以通过理解问题概念,使得程序更加容易编写、调试和修改。类的基本思想是数据抽象(dataabstraction)和封装(encapsulation)。数据抽象是一种依赖于接口(interface)和实现(implementation)分离的编程(以及设......
  • c++ 科幻版 沙漠神殿2
    #include<iostream>#include"minecraft.h"#include<string>usingnamespacestd;TxMinecraftmc;intx,y,z;boolcon;boollianjie(){ returncon=mc.ConnectMinecraft("mc.makeblock.net.cn","a9d44e758f6e4cf8b2da26241......
  • 请使用C++计算出2^2023与3^2023的和
    易知,这个和的数字是非常大的,大到longlong都装不下,这个时候如果使用longlong是无法进行运算的。欸!这会高精度算法(即大数运算)就开始发光发热了。以下是我看资料总结的一些歪瓜裂枣。对于一位高精度数字,用整数数组存储,数组每一个元素对应一位十进制数,由其下标顺序指明位序号......
  • 2023年7月7日,线程池的调用原理,线程池底层,任务队列
    线程池的调用原理线程池的七大参数:核心线程数、最大线程数、任务队列、拒绝策略、闲置时间、时间单位、线程工厂任务进入线程池后线程池的执行顺序:核心线程(用完)---处理完一个任务后会取出任务队列中的第一个任务来执行任务队列(装满)普通线程(用完)拒绝策略深入线程池ExecutorServicep......
  • 进程与线程的一个简单解释
    进程(process)和线程(thread)是操作系统的基本概念,但是它们比较抽象,不容易掌握。最近,我读到一篇材料,发现有一个很好的类比,可以把它们解释地清晰易懂。1.计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。2.假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一......
  • 进程池和线程池
    一、进程池1、进程池 ProcessPoolExecutor优点:减少进程创建和销毁的开销:创建和销毁进程是一个相对耗时的操作,涉及到操作系统的系统调用和资源分配。使用进程池,可以预先创建一组进程,并在需要时重用这些进程,避免了频繁的进程创建和销毁开销,提高了程序的性能和效率。控制并......
  • 进程与线程的一个简单解释
    进程(process)和线程(thread)是操作系统的基本概念,但是它们比较抽象,不容易掌握。最近,我读到一篇材料,发现有一个很好的类比,可以把它们解释地清晰易懂。1. 计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。2. 假定工厂的电力有限,一次只能供给一个车间......
  • c++沙漠神殿
    #include<iostream>#include"minecraft.h"#include<string>usingnamespacestd;TxMinecraftmc;intx=0,y=0,z=0;intmain(intargc,char**argv){boolcon=mc.ConnectMinecraft("zk.makeblock.net.cn","a9d44e758f6e4cf8b......
  • Java线程池详解:Future的使用和实现
    提交到线程池中执行的异步任务都会返回一个任务的Future,所以这里先介绍一下Future的使用和实现。异步任务通常会被提交到线程池中去执行,但任务并非提交到线程池后就不管不顾了,在某些时刻我们希望能够取消任务,同时也希望在任务执行完成后获取到任务的执行结果。Java提供了Futur......