C++实现多线程
C89→C99→C11
C++98/03→C++11→C++14→C++17
Linux是一类Unix计算机操作系统的统称,在1991 年的十月,由一个名为 Linus Torvalds的年轻芬兰大学生带头开发的作业系统。
linux和unix操作系统的设计采用的是多进程,进程间的通信十分方便,同时进程之间互相有着独立的空间,不会污染其他进程的数据,天然的隔离性给程序的稳定性带来了很大的保障。而线程一直都不是linux和unix推崇的技术,甚至有传言说linus本人就非常不喜欢线程的概念。随着C++市场份额被Java、Python等语言所蚕食,为了使得C++更符合现代语言的特性,在C++11中引入了多线程与并发技术。
传统的C++(C++98)中并没有引入线程这个概念。
在c++11中,使用了类对象thread即线程类来实现,需要引入头文件thread,对于一个thread类的创建对象即开始了一个线程。
使用方法:
thread first(函数名,参数1,参数2……);
注意:多线程的实现方式是利用cpu空闲时间来跑其他线程的任务,但是在进入其他线程时就必须消耗时间来保存上一个线程和打开下一个线程,因此多线程并不是一定效率就比顺序执行效率高。
单核CPU和C++11以前实现的并发一般是伪并发。随着多核CPU的普及,C++11开始支持真正意义上的并发。
C++11可以通过多线程实现并发,这是一种比较底层、传统的实现方式。
C++11引入了5个头文件来支持多线程编程:<atomic>、<thread>、<mutex>、<condition_variable>、<future>
#include <atomic> // C++11 原子操作,限制并发程序对共享数据的使用,避免数据竞争
#include <thread> // 该头文件主要声明了std::thread类,另外std::this_thread命名空间也在该头文件中
#include <mutex> // C++11 互斥量Mutex。在多线程环境中,有多个线程竞争同一个公共资源,就很容易引发线程安全的问题
#include <condition_variable> // C++11 并发编程 主要包含了与条件变量相关的类和函数
#include <future> //可以通过特殊的provider进行数据的异步访问,实现线程间的通信
进程的构成:程序、数据、PCB(进程控制块)
进程在创建、撤销和切换中,系统必须为之付出较大的时空开销,因此系统中开启的进程数不宜过多。
线程是进程中的一个实体,线程是独立调度的基本单位,CPU可执行调度的最小单位。进程本身并不能获取CPU时间,只有它的线程才可以。线程基本上不拥有资源,只拥有一点运行中必不可少的资源,它可与同属一个进程的其他线程共享进程所拥有的全部资源。同一个进程中的多个线程可以并发执行。
线程分为用户级线程和内核支持线程两类:
1.用户级线程不依赖于内核,该类线程的创建、撤销和切换都不利用系统调用来实现;
2.内核支持线程依赖于内核,即无论是在用户进程中的线程,还是在系统中的线程,其创建、撤销和切换都利用系统调用来实现。
系统进程和用户进程在进行切换时都要依赖于内核中的进程调度。
在一个应用程序(进程)中同时执行多个小的部分(线程),这就是多线程。
多个线程虽然共享一样的数据,但是却执行不同的任务。