1什么是C++多线程并发? 1.1 线程的概念与多线程: 线程是操作系统*能够进行CPU调度的最小单 位,它被包含在进程之中,一个进程可包含单 个或者多个线程。 在Linux中可以更容易观察到并理解线程,写 一个如下程序:
// main.cpp
include
void func()
{
int i=0;
while(true);
}
int main()
{
std::thread th(func);
th.detach();
while(true);
return 0;编译并执行如上程序:
$ g++ main.cpp
启用两个shell终端,在一个终端中运行:
$ ./a.out
在另一个终端中运行:
$ ps -feL | grep 1747
UID PID PPID LWP C NLWP STIME TTY TIME CMD
zhengzu+ 1747 357 1747 98 2 23:02 pts/0 00:00:24 ./a.out
zhengzu+ 1747 357 1748 98 2 23:02 pts/0 00:00:24 ./a.out
PID为processid,进程ID
LWP为light weight process orthread, 即线程ID
即可观察到,该代码以一个进程的方式运行, 进程ID为1747,该进程包含两个线程: 一个是主线程1747,主线程ID同进程ID(只是 ID相同,并不指两者是一个东西),main函 数在主线程中运行; 另一个是子线程1748,由代码std::thread th(func)生成该线程,函数func在子线程中运 行; (简单情况下)实现多线程并发程序的思路如 下:将任务的不同功能交由多个函数分别实 现,创建多个线程,每个线程执行一个函数, 一个任务就这样同时分由不同线程执行了。 用生活中的实际具体,可以将做饭用一个程序 实现,有一个大厨(主线程)指挥小王(线程 2)去洗菜(函数func1),小李(线程3)去切菜 (函数func2),小白(线程4)去洗碗(函数 func3); 亦可见,多个线程之间存在同步与异步关系, 如要先洗菜再才能切菜(同步关系),洗菜“ 洗碗互不影响(异步关系);
C++中有相应的手段来解决线程的同步与异 步,后面会学到; 我们通常在何时使用并发? 程序使用并发的原因有两种: 1.为了关注点分离(程序中不同的功能,使用 不同的线程去执行),当为了分离关注点而 使用多线程时,设计线程的数量的依据,不 再是依赖于CPU中的可用内核的数量,而是 依据概念上的设计(依据功能的划分); 2.为了提高性能,此时线程数量可以依据CPU 的逻辑核心数目,这样可以使得每个线程能 在不同的CPU核心上同时并发执行; 知道何时不使用并发与知道何时使用它一样重 要。 不使用并发的唯一原因就是收益(性能的增 幅)比不上成本(代码开发的脑力成本、时间 成本,代码维护相关的额外成本)。运行越多 的线程,操作系统需要为每个线程分配独立的 栈空间,需要越多的上下文切换*,这会消耗很 多操作系统资源,如果在线程上的任务完成得 很快,那么实际执行任务的时间要比启动线程
的时间小很多,所以在某些时候,增加一个额 外的线程实际上会降低,而非提高应用程序的 整体性能,此时收益就比不上成本。而且多线 程代码如果编写不当,运行中会出现很多问 题,诸如执行结果不符合预期、程序崩溃等问 题。
请登录后发表评论
注册
停留在世界边缘,与之惜别