菜鸟笔记
提升您的技术认知

操作系统笔记

进程,线程,协程与并行,并发进程线程协程的区别死锁进程,线程,多线程i++的线程安全性同步和异步孤儿进程和僵尸进程/proc进程信息linux中的分段和分页互斥量 mutex线程进程间通信进程创建进程优先级进程的基础知识进程与线程的区别(面试题)线程的控制(创建,终止,等待,分离)可重入 VS 线程安全死锁的概念一级缓存和二级缓存的理解一句话解说内存屏障 Memory barrierbrk(), sbrk() 用法详解malloc/free函数的简单实现一文讲透 “进程、线程、协程”Linux进程状态线程池的陷阱linux内核学习之进程和线程进程与线程的区别和联系内存寻址linux IO子系统和文件系统读写流程Page cache和buffer cache的区别与联系漫谈linux文件IO多线程和多进程的区别内存泄漏字节、字、位、比特的概念和关系如何避免死锁ANSI是什么编码?CPU寻址范围(寻址空间)CPU 使用率低高负载的原因创建多少个线程合适操作系统下spinlock锁解析、模拟及损耗分析线程堆栈堆和栈的内存分配堆和栈的概念和区别堆和栈的区别,申请方式,程序的内存分配什么是 POD 数据类型Linux内存分配小结--malloc、brk、mmap系统调用与内存管理(sbrk、brk、mmap、munmap)进程描述和控制CPU执行程序的原理编译的基本概念Linux虚拟地址空间布局一个程序从源代码到可执行程序的过程程序的运行机制——CPU、内存、指令的那些事分页内存管理——虚拟地址到物理地址的转换深刻理解Linux进程间通信fork之后父子进程的内存关系fork之后,子进程继承了父进程哪些内容关于协程及其锁的一些认识对协程的一点理解std::thread join和detach区别CAS和ABA问题CAS算法锁和无锁无锁队列的实现Lock-Free 编程锁开销优化以及CAS

进程,线程,多线程

阅读 : 337

进程,线程,多线程

进程与线程:

进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位.      【占用资源的最小单元】

线程:它是比进程更小的能独立运行的基本单位是进程的一个实体,CPU调度和分派的基本单位。它只拥有运行中必不可少的资源(如程序计数器,一组寄存器和栈),但它可与同属一个进程的其他的线程共享进程所拥有的全部资源.             【调度的单位】  

关系:

1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

2)一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。进程之间也可以并发执行.

3)资源分配给进程,同一进程的所有线程共享该进程的所有资源。

4)处理机分给线程,即真正在处理机上运行的是线程。

5)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

区别:

(1)  拥有资源和调度:进程是拥有资源的独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。线程是指进程内的一个执行单元
是调度和分配的基本单位,

(2)  通信:线程之间的通信比较方便。统一进程下的线程共享数据(比如全局变量,静态变量),通过这些数据来通信,快捷方便,但要处理好这些访问的同步与互斥。而进程之间的通信只能通过进程通信的方式进行(如管道,信号,消息队列,共享内存,信号量,套接字)。

(3)  执行:每个独立的线程有自己的一个程序入口,顺序执行序列和程序的出口,但是不能独立执行,必须依附与程序之中,由应用程序提供多个线程的并发控制。

(4)  系统开销:进程有独立的地址空间,在创建或撤消进程时,系统都要为之分配和回收资源,导致开销明显大。运行一个进程中的线程,共享大部分数据,使用相同的地址空间,因此启动一个线程,切换一个线程远比进程操作要快,花费也要小得多。

(5)  健壮性:多进程的程序要比多线程的程序健壮。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响。而线程只是一个进程中的不同执行路径,有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉。

线程安全:

   多线程的程序运行结果是可预期的,而且与单线程的程序运行结果一样。

线程状态:

就绪、运行、阻塞、挂起阻塞、挂起就绪

多线程:

1.    多线程互斥与同步有几种实现方法?都是什么?

临界区(CS:critical section)、互斥量(Mutex);事件(Event)、信号量(semaphores)。

a.    临界区(同一个进程内,实现互斥): 在任意时刻只允许一个线程对共享资源进行访问,其他的被挂起,直到临界区被释放。【多线程的串行化,速度快,适合控制数据访问】

b.    互斥量(可以跨进程,实现互斥):只有拥有互斥对象(只有一个)的线程才具有访问资源的权限,当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。【为协调对一个共享资源的单独访问而设计】

###  临界区 VS  互斥量 :

   两者都可以用于同一进程中不同子线程对资源的互斥访问。互斥量可以很好的解决由于线程意外终止资源无法释放的问题。互斥量是内核对象,可以命名,也就是说它可以跨进程使用,所以创建互斥量需要的资源更多。在进程内部,使用临界区会更快。

c.    事件(实现同步,可以跨进程):用来通知线程有一些事件已发生,从而启动后继任务的开始。

d.    信号量(主要是实现同步,可以跨进程): 它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。【为控制一个具有有限数量用户资源而设计】

线程间的同步方法大体可分为两类:用户模式和内核模式。顾名思义,内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,而用户模式就是不需要切换到内核态,只在用户态完成操作。

用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。内核模式下的方法有:事件,信号量,互斥量。

2.    C++中多线程实现方法:

C++ 11新特性中,可以使用std::thread来创建线程。Windows系统提供了相关API,我们可以使用他们来进行多线程编程。

例子:C++多线程编程实例

线程随机交替运行,运行时间不一样,可能主线程运行完之后将所占资源都释放掉了,使得子线程还没有运行完。 【可用sleep()】

注意进程之间会被打断。如:

cout << "Main Thread Display!" <改成cout << "Main ThreadDisplay!\n";

【用互斥量(Mutex)来进行线程同步,允许一个线程拥有对共享资源的独占。】

3.    多线程同步和互斥有何异同,在什么情况下分别使用他们?举例说明
同步,指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。

互斥,指对于共享的进程系统资源,在各单个线程访问时的排它性。线程互斥可以看成是一种特殊的线程同步。”不能同时访问,是个顺序问题“。

举例,设有一个全局变量global,为了保证线程安全,我们规定只有当主线程修改了global之后下一个子线程才能访问global,这就需要同步主线程与子线程,可用关键段实现。当一个子线程访问global的时候另一个线程不能访问global,那么就需要互斥。