C++进阶 多线程相关(上)

简介: C++进阶 多线程相关

为什么要有线程库

我们在Linux中写多线程的时候使用的是Linux下提供的多线程的一套api

但是如果我们的运行环境变成了windows呢 windows提供的多线程api肯定和Linux不同

也就是说 我的代码可移植性很差 这个时候如果有一个语言层面的库就能解决移植性的问题了

而在C++11中最重要的特性就是对线程进行支持了 使得C++在并行编程时不需要依赖第三方库 而且在原子操作中还引入了原子类的概念 要使用标准库中的线程 必须包含thread头文件

线程库介绍

线程库常见的接口

成员函数 用处
thread() 构造一个线程对象,没有关联任何线程函数,即没有启动任何线程
get_id() 获取线程id
jionable() 线程是否还在执行,joinable代表的是一个正在执行中的线程。
jion() 该函数调用后会阻塞住线程,当该线程结束后,主线程继续执行
detach() 在创建线程对象后马上调用,用于把被创建线程与线程对象分离开,分离的线程变为后台线程,创建的线程的"死活"就与主线程无关


构造线程对象

54affd0e12b4480cb6ee8acd1d9b1a24.png

方式一 : 无参构造

函数如下

thread();

这是一个无参构造 所以说创建出来之后并没有任何的任务与其相关联 如果我们需要使用移动构造赋予其一个任务

代码表示如下

void func(int n)
{
  for (int i = 0; i < n; i++)
  {
    cout << i << endl;
  }
}
int main()
{
  thread t1;
  t1 = thread(func, 10);
  t1.join();
  return 0;
}

方式二: 带参构造

函数如下

template <class Fn, class... Args>
explicit thread (Fn&& fn, Args&&... args);

此时我们只需要省略无参构造t1的过程 直接使用构造函数即可 代码表示如下

void func(int n)
{
  for (int i = 0; i < n; i++)
  {
    cout << i << endl;
  }
}
int main()
{
  thread t1(func, 10);
  t1.join();
  return 0;
}

方式三 拷贝构造

在C++中的thread库中 我们禁止了拷贝构造 在这里特地强调下

方式四 移动构造

函数如下

thread (thread&& x) noexcept;

使用方式和第一种无参构造很类似 代码表示如下

void func(int n)
{
  for (int i = 0; i < n; i++)
  {
    cout << i << endl;
  }
}
int main()
{
  thread t1 = thread(func, 10);
  t1.join();
  return 0;
}


获取线程id

函数原型如下

this_thread::get_id()

我们可以使用该函数来获取线程的id 代码和运行结果如下

void func(int n)
{
  cout << this_thread::get_id() << endl;
}
int main()
{
  thread t1 = thread(func, 10);
  t1.join();
  return 0;
}

71513a03b95f476aaa7a9546fcfc3da1.png

join和deteach

thread库中提供给我们这两个函数的用途主要是让我们去回收我们的线程资源

join

当我们调用 join() 函数的时候主线程会被阻塞

当新线程终止的时候主线程回去回收对应的资源 代码和运行结果如下

void func(int n)
{
  cout << this_thread::get_id() << endl;
}
int main()
{
  thread t1 = thread(func, 10);
  t1.join();
  return 0;
}

39e1087336f046848da9d1850c98c6ab.png

注意点:

  • join的作用是回收资源 如果说我们连续对于一个地方回收两次资源则会造成程序崩溃

deteach

当我们调用 deteach() 函数的时候 就相当于主线程和新线程之间没有关系了

各跑各的

代码和示例如下

void func(int n)
{
  cout << this_thread::get_id() << endl;
}
int main()
{
  thread t1 = thread(func, 10);
  t1.join();
  Sleep(1);
  return 0;
}

9fa23dce3cf14fad9b6b47e7e81625da.png

注意点:

  • 我们在主线程的代码中如果不加sleep(1) 那么有可能新线程还没跑起来 整个进程就运行结束
相关文章
|
19天前
|
缓存 安全 C++
C++无锁队列:解锁多线程编程新境界
【10月更文挑战第27天】
33 7
|
19天前
|
消息中间件 存储 安全
|
1月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
44 1
C++ 多线程之初识多线程
|
25天前
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
|
1月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
46 6
|
1月前
|
缓存 负载均衡 Java
c++写高性能的任务流线程池(万字详解!)
本文介绍了一种高性能的任务流线程池设计,涵盖多种优化机制。首先介绍了Work Steal机制,通过任务偷窃提高资源利用率。接着讨论了优先级任务,使不同优先级的任务得到合理调度。然后提出了缓存机制,通过环形缓存队列提升程序负载能力。Local Thread机制则通过预先创建线程减少创建和销毁线程的开销。Lock Free机制进一步减少了锁的竞争。容量动态调整机制根据任务负载动态调整线程数量。批量处理机制提高了任务处理效率。此外,还介绍了负载均衡、避免等待、预测优化、减少复制等策略。最后,任务组的设计便于管理和复用多任务。整体设计旨在提升线程池的性能和稳定性。
78 5
|
1月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
25 0
C++ 多线程之线程管理函数
|
1月前
|
资源调度 Linux 调度
Linux C/C++之线程基础
这篇文章详细介绍了Linux下C/C++线程的基本概念、创建和管理线程的方法,以及线程同步的各种机制,并通过实例代码展示了线程同步技术的应用。
29 0
Linux C/C++之线程基础
|
3月前
|
Java 调度
基于C++11的线程池
基于C++11的线程池
|
4月前
|
算法 编译器 C++
开发与运维线程问题之在C++的原子操作中memory_order如何解决
开发与运维线程问题之在C++的原子操作中memory_order如何解决
46 2