标签:保护 mic alt 网络 时间片 name col 同步 src
先将两个概念,
并发:同一时间段内可以交替处理多个操作:
图中整个安检系统是一个并发设计的结构。两个安检队列队首的人竞争这一个安检窗口,两个队列可能约定交替着进行安检,也可能是大家同时竞争安检窗口(通信)。后一种方式可能引起冲突:因为无法同时进行两个安检操作。在逻辑上看来,这个安检窗口是同时处理这两个队列
并行:同一时刻内同时处理多个操作:
图中整个安检系统是一个并行的系统。在这里,每个队列都有自己的安检窗口,两个队列中间没有竞争关系,队列中的某个排队者只需等待队列前面的人安检完成,然后再轮到自己安检。在物理上,安检窗口同时处理这两个队列。
并发的程序设计,提供了一种方式让我们能够设计出一种方案将问题(非必须地)并行地解决。如果我们将程序的结构设计为可以并发执行的,那么在支持并行的机器上,我们可以将程序并行地执行。因此,并发重点指的是程序的设计结构,而并行指的是程序运行的状态。并发编程,是一种将一个程序分解成小片段独立执行的程序设计方法。
维基百科对线程的定义是:线程是一个编排好的指令序列,这个指令序列(线程)可以和其它的指令序列(线程)并行执行,操作系统调度器将线程作为最小的 CPU 调度单元。
图 1、单个 CPU 内核上的多个线程运行示意图
我们可以看到,这时的多线程本质上是单个 CPU 的时间分片,一个时间片运行一个线程的代码,它可以支持并发处理,但是不能说是真正的并行计算。
图 2、双核 CPU 上的多个线程运行示意图
从上述两图,我们可以直接得到使用多线程的一些常见场景:
多线程与多进程是并发的两种途径。
前面也讲到了并发的两个场景:非阻塞、并行执行子任务
多个进程独立地运行,它们之间通过进程间常规的通信渠道传递讯息(信号,套接字,文件,管道等),这种进程间通信不是设置复杂就是速度慢,这是因为为了避免一个进程去修改另一个进程,操作系统在进程间提供了一定的保护措施,当然,这也使得编写安全的并发代码更容易。
运行多个进程也需要固定的开销:进程的启动时间,进程管理的资源消耗。
在当个进程中运行多个线程也可以并发。线程就像轻量级的进程,每个线程相互独立运行,但它们共享地址空间,所有线程访问到的大部分数据如指针、对象引用或其他数据可以在线程之间进行传递,它们都可以访问全局变量。进程之间通常共享内存,但这种共享通常难以建立且难以管理,缺少线程间数据的保护。因此,在多线程编程中,我们必须确保每个线程锁访问到的数据是一致的。
C++标准并没有提供对多进程并发的原生支持,所以C++的多进程并发要靠其他API——这需要依赖相关平台。
C++11 标准提供了一个新的线程库,内容包括了管理线程、保护共享数据、线程间的同步操作、低级原子操作等各种类。标准极大地提高了程序的可移植性,以前的多线程依赖于具体的平台,而现在有了统一的接口进行实现。
C++11 新标准中引入了几个头文件来支持多线程编程:
我们从一个hello开始。在单线程时:
#include<iostream> using namespace std; int main() { cout<<"hello world"<<endl; }
在这里,进程由一个线程组成,该线程的初始函数是main。我们启动第二个线程来打印hello world:
# include<iostream> # include<thread> using namespace std; void hello() { cout<<"hello world"<<endl; } int main() { thread t(hello); t.join(); }
每个线程都必须有一个初始函数,新线程的执行开始于初始函数;
程序由两个线程组成:初始线程始于main,新线程始于hello。这里将新线程t的初始函数指定为hello;
新线程启动之后会与初始进程一并运行,初始线程可以等待或不等待新进程的运行结束——如果需要等待线程,则新线程实例需要使用join(),否则可以使用detach()。如果不等待新线程,则初始线程自顾自地运行到main()结束。
在我们编写出的第一个多线程的程序,一般来说并不值得为了如此简单的任务而使用多线程,尤其是在这期间初始线程并没做什么。
参考链接:
1. IBM-使用 C++11 编写 Linux 多线程程序
标签:保护 mic alt 网络 时间片 name col 同步 src
原文地址:https://www.cnblogs.com/lfri/p/12419266.html