罗剑锋的C++实战笔记16-十面埋伏的并发:多线程真的很难吗?

今天,我们来聊聊“并发”(Concurrency)、“多线程”(multithreading)。

在 20 年前,大多数人(当然也包括我)对这两个词还是十分陌生的。那个时候,CPU 的性能不高,要做的事情也比较少,没什么并发的需求,简单的单进程、单线程就能够解决大多数问题。

但到了现在,计算机硬件飞速发展,不仅主频上 G,还有了多核心,运算能力大幅度提升,只使用单线程很难“喂饱”CPU。而且,随着互联网、大数据、音频视频处理等新需求的不断涌现,运算量也越来越大。这些软硬件上的变化迫使“并发”“多线程”成为了每个技术人都不得不面对的课题。

通俗地说,“并发”是指在一个时间段里有多个操作在同时进行,与“多线程”并不是一回事。

并发有很多种实现方式,而多线程只是其中最常用的一种手段。不过,因为多线程已经有了很多年的实际应用,也有很多研究成果、应用模式和成熟的软硬件支持,所以,对这两者的区分一般也不太严格,下面我主要来谈多线程。

认识线程和多线程

要掌握多线程,就要先了解线程(thread)。

线程的概念可以分成好几个层次,从 CPU、操作系统等不同的角度看,它的定义也不同。今天,我们单从语言的角度来看线程。

在 C++ 语言里,线程就是一个能够独立运行的函数。比如你写一个 lambda 表达式,就可以让它在线程里跑起来:

auto f = []() // 定义一个lambda表达式

{

cout << "tid=" <<

this_thread::get_id() << endl;

};

thread t(f); // 启动一个线程,运行函数f

任何程序一开始就有一个主线程,它从 main() 开始运行。主线程可以调用接口函数,创建出子线程。子线程会立即脱离主线程的控制流程,单独运行,但共享主线程的数据。程序创建出多个子线程,执行多个不同的函数,也就成了多线程。

多线程的好处你肯定能列出好几条,比如任务并行、避免 I/O 阻塞、充分利用 CPU、提高用户界面响应速度,等等。

不过,多线程也对程序员的思维、能力提出了极大的挑战。不夸张地说,它带来的麻烦可能要比好处更多。

这个问题相信你也很清楚,随手就能数出几个来,比如同步、死锁、数据竞争、系统调度开销等……每个写过实际多线程应用的人,可能都有“一肚子的苦水”。

其实,多线程编程这件事“说难也不难,说不难也难”。这句话听上去好像有点自相矛盾,但却有一定的道理。为什么这么说呢?

说它不难,是因为线程本身的概念是很简单的,只要规划好要做的工作,不与外部有过多的竞争读写,很容易就能避开“坑”,充分利用多线程,“跑满”CPU。

说它难,则是因为现实的业务往往非常复杂,很难做到完美的解耦。一旦线程之间有共享数据的需求,麻烦就接踵而至,因为要考虑各种情况、用各种手段去同步数据。随着线程数量的增加,复杂程度会以几何量级攀升,一不小心就可能会导致灾难性的后果。

多线程涵盖的知识点太多,许多大师、高手都不敢自称精通,想用一节课把多线程开发说清楚是完全不可能的。

所以,今天我们只聚焦 C++ 的标准库,了解下标准库为多线程编程提供了哪些工具,在语言层面怎么改善多

  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员zhi路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值