进程 & 线程相关知识
不管Java,C++都有进程、线程相关的内容。在这里统一整理吧。
Python的线程,其实是伪线程,不能真正的并发。下面也有讲。
线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈)。
多个线程共享内存。
参考了这篇文章:http://www.cnblogs.com/qiaoconglovelife/p/5319779.html
进程与PCB
进程:进程是程序的一次执行过程,是系统进行资源分配和调度的一个独立单位。
进程实体(进程映像):由程序段、相关数据段和PCB三部分构成。进程是动态的,进程实体是静态的。
PCB(进程控制块):系统利用PCB来描述进程的基本情况和运行状态,进而控制和管理进程;所谓创建进程,实际上是创建进程映像中的PCB;PCB是进程存在的唯一标志。
进程有5种状态,其中前3种是基本状态:
运行态、就绪态、阻塞态(等待态)。另两种是新建态和终止态。
进程的创建过程
(1)分配ID与PCB:为新进程分配一个唯一的进程标识号,并申请一个空白的PCB(PCB是有限的)。若PCB申请失败则创建失败。
(2)分配资源:为新进程的程序和数据、以及用户栈分配必要的内存空间(在PCB 中体现)。注意:这里如果资源不足(比如内存空间),并不是创建失败,而是处于阻塞态。
(3)初始化PCB:主要初始化(1)标志信息(2)处理机状态信息(3)处理机控制信息,以及(4)设置进程的优先级等。
(4)调度:如果进程就绪队列能够接纳新进程,就将新进程插入到就绪队列,等待被调度运行。
注意,进程的创建是一个原子操作,执行期间不允许中断,它是一个不可分割的基本单位。
进程的终止
引起进程终止的事件主要有:
(1)正常结束
(2)异常结束:如存储区越界、非法指令、I/O故障等
(3)外界干预:如操作员或操作系统干预、父进程请求、父进程终止。
操作系统终止进程的过程如下:
(1)根据被终止进程的ID,检索PCB,从中读出该进程的状态
(2)若被终止进程处于执行状态,立即终止该进程的执行,将处理机资源分配给其他进程
(3)若该进程还有子进程,则应将其所有的子进程终止
(4)将该进程所拥有的资源,或归还给其父进程或归还给操作系统
(5)将该PCB从所在队列(链表)中删除。
进程之间的切换
(1)保存处理机上下文,包括程序计数器和其他寄存器。
(2)更新PCB信息。
(3)把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列。
(4)选择另一个进程执行,并更新其PCB。
(5)更新内存管理的数据结构。
(6)恢复处理机上下文。
注意:“调度”和“切换”的区别:调度是指决定资源分配给哪个进程的行为,是一种决策行为;切换是指实际分配的行为,是执行行为。一般来说,等有资源的调度,再有进程的切换。
线程
线程是轻量化的进程,是程序执行流的最小单位;由线程ID、程序计数器、寄存器集合和堆栈组成;线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。
进程与线程区别
(1)一个程序至少有一个进程,一个进程至少有一个线程。线程(Thread)是进程的一个实体,是CPU调度和分派的基本单位;
(2)进程拥有独立的内存单元,而多个线程共享内存。从而线程效率更高;
(3)进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮;
(4)进程切换时,耗费资源较大,效率要差一些;
(5)进程是系统资源分配的基本单位,线程是调度的基本单位。
线程独有的内容:线程上下文,包括线程ID、栈、栈指针、PC(程序计数器)、通用目的寄存器、条件码。
线程共享的内容:文件描述符和整个用户虚拟地址空间,包括只读文本(代码)、静态变量、堆、所有的共享库代码和数据区域组成。
相比进程,线程有什么好处
(1)易于调度。
(2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。
(3)开销少。创建线程比创建进程要快,所需开销很少。。
(4)利于充分发挥多处理器的功能。
相比进程,线程有什么缺点
(1)线程之间的同步和加锁控制比较麻烦
(2)一个线程的崩溃影响到整个程序的稳定性
(3)线程多了之后,线程本身的调度也是一个麻烦事儿,需要消耗较多的CPU
分离线程
- 线程可以是可结合的,或者是可分离的;
- 可结合的线程能够被其他线程收回其资源和杀死。在被其他线程回收之前,它的存储器资源(例如栈)是没有被释放的,相反一个分离的线程是不能被其他线程回收或杀死的。它的存储器资源在它终止时由系统自动释放;
- 为避免存储器泄漏,每个可结合线程都应该被其他线程显式地收回,要么通过调用pthread_detach函数被分离;(对应于Java就是 Thread.join和Thread.detach )
- 默认情况下,线程被创建成可结合的。(注意:可结合是一种状态,要调用join方法来进行结合/释放)
来一个例子:
package com.company; import static java.lang.Thread.sleep; class Solution { } class MyRunnable implements Runnable { int x = 5;
@Override
public void run() {
synchronized(this) {
for (int i = 0; i < 5; i++) {
System.out.println("hi " + Thread.currentThread().getName() + ":" + x--);
}
}
System.out.println("here to sleep");
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public class Main { public static void main(String[] args) throws InterruptedException { MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr, "1");
Thread t2 = new Thread(mr, "2");
Thread t3 = new Thread(mr, "3"); t1.start();
t2.start();
t3.start(); System.out.println(); } }
打印结果:
hi 1:5
hi 1:4
hi 1:3
hi 1:2
hi 1:1
here to sleep
hi 3:0
hi 3:-1
hi 3:-2
hi 3:-3
hi 3:-4
here to sleep hi 2:-5
hi 2:-6
hi 2:-7
hi 2:-8
hi 2:-9
here to sleep
三个线程,同时sleep了5秒钟,然后整个程序才结束。
如果synchronized加在函数上,那么是每个线程分别sleep 5秒钟,一共sleep 15秒钟。
IPC方式(进程间通信方式)
(1)管道:半双工;用于父子、兄弟之间。
(2)命名管道(FIFO)
(2)消息队列:消息链表存于内核,每个消息队列由消息队列标识符标识;于管道不同的是,消息队列存放在内核中,只有在内核重启时才能删除一个消息队列;消息队列的大小受限制。
(3)信号量(semophore):常用来处理临界资源的访问同步问题。临界资源:为某一时刻只能由一个进程或线程操作的资源。
(4)共享内存:可以说是最有用的进程间通信方式,也是最快的IPC形式。
(5)套接字:也可用于不同机器之间。
(6)信号(Signal)
线程同步方式
(1)临界区:当多个线程访问一个独占性共享资源时,可以使用临界区对象。拥有临界区的线程可以访问被保护起来的资源或代码段,其他线程若想访问,则被挂起,直到拥有临界区的线程放弃临界区为止。
(注:Java的synchronized代码段,也勉强可以算作临界区,只是语言标记互斥的实现方式;要访问代码段,需要获得传给synchronized的Object这个对象的锁。注意,每个java对象都隐含有一把锁。
Java GC需要的safe point,为了让多个线程都停下来,标记的区域-其他线程不进来,里面的线程出来了,就开始GC- 跟临界区的思想也有一点像)
(2)互斥量-mutex:互斥对象和临界区对象非常相似,只是其允许在进程间使用,而临界区只限制与同一进程的各个线程之间使用。
(3)条件变量:一个线程被挂起,直到某件事件发生。
(4)信号量:当需要一个计数器来限制可以使用某共享资源的线程数目时,可以使用“信号量”对象。CSemaphore类对象保存了对当前访问某一个指定资源的线程的计数值,该计数值是当前还可以使用该资源的线程数目。如果这个计数达到了零,则所有对这个CSemaphore类对象所控制的资源的访问尝试都被放入到一个队列中等待,直到超时或计数值不为零为止。
(5)事件:允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。
(6)套接字
感觉上面这篇文章不错,有一定深度。可以多看看这个博客:http://www.cnblogs.com/qiaoconglovelife/
再来聊一下Python的线程
简单地说就是作为可能是仅有的支持多线程的解释型语言(perl的多线程是残疾,PHP没有多线程),Python的多线程是有compromise的,在任意时间只有一个Python解释器在解释Python bytecode。Ruby也是有thread支持的,而且至少Ruby MRI是有GIL的。
单独开了一篇文章来写,详细内容可以看这篇文章:http://www.cnblogs.com/charlesblc/p/6135819.html
看一下Javascript里面的线程
JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序. 详细学习见这篇文章:
进程 & 线程相关知识的更多相关文章
- linux 创建守护进程的相关知识
linux 创建守护进程的相关知识 http://www.114390.com/article/46410.htm linux 创建守护进程的相关知识,这篇文章主要介绍了linux 创建守护进程的相关 ...
- 浅谈C#中的 async await 以及对线程相关知识的复习
C#5.0以后新增了一个语法糖,那就是异步方法async await,之前对线程,进程方面的知识有过较为深入的学习,大概知道这个概念,我的项目中实际用到C#异步编程的场景比较少,就算要用到一般也感觉T ...
- 面试4——java进程和线程相关知识
1.线程和进程的概念.并行和并发的概念
- MFC中线程相关知识
MFC中把线程分为两种类型,UI线程和工作者线程. MFC中启动一个线程的最好方法是调用AfxBeginThread,有两个版本,一个用于启动Ui线程,另外一个用于启动工作者线程.在MFC程序中,只有 ...
- Linux进程快照相关知识
查寻内核版本 uname -a // uname -r 进程快照 ps report a snapshot of the current processes USER ...
- [Chapter 3 Process]Practice 3.1 相关知识:进程创建、fork函数
3.1 Using the program shown in the Figure3.30, explain what the output will be at LINE A 答案:LINE A 处 ...
- 测试必备之Java知识(四)—— 线程相关
线程相关 Java多线程实现方式 继承Thread,实现Runnable接口,实现Callable接口(能抛异常且有返回值,不常用) 为什么有了继承Thread方式还要有Runnable接口方式 实现 ...
- 浅谈Excel开发:十 Excel 开发中与线程相关的若干问题
采用VSTO或者Shared Add-in等技术开发Excel插件,其实是在与Excel提供的API在打交道,Excel本身的组件大多数都是COM组件,也就是说通过Excel PIA来与COM进行交互 ...
- windows进程/线程创建过程 --- windows操作系统学习
有了之前的对进程和线程对象的学习的铺垫后,我们现在可以开始学习windows下的进程创建过程了,我将尝试着从源代码的层次来分析在windows下创建一个进程都要涉及到哪些步骤,都要涉及到哪些数据结构. ...
随机推荐
- JavaScript DOM 编程艺术(第2版)读书笔记(3)
DOM DOM:文档对象模型: 节点 元素节点:DOM的原子是元素节点.<body>.<p>.<ul>之类的元素.元素可以包含其他的元素.没有被包含在其他元素里的唯 ...
- ScheduledExecutorService定时周期执行指定的任务
示例代码 package com.effective.common.concurrent.execute; import java.text.DateFormat; import java.text. ...
- stl map底层之红黑树插入步骤详解与代码实现
转载注明出处:http://blog.csdn.net/mxway/article/details/29216199 本篇文章并没有详细的讲解红黑树各方面的知识,只是以图形的方式对红黑树插入节点需要进 ...
- 20150825 C# 调用带参数的存储过程 模板
////// exec proceudre2 //System.Data.SqlClient.SqlConnection sqlcon = new Sys ...
- 查找练习 hash——出现过的数字 分类: 查找 2015-06-18 17:30 7人阅读 评论(0) 收藏
查找练习 hash--出现过的数字 *Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 有一个数据字典,里面存有n个数字(n<=10 ...
- 2016年省赛G题, Parenthesis
Problem G: Parenthesis Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 398 Solved: 75[Submit][Status ...
- Mysql-学习笔记(==》事件 十二)
事件 计划任务(定期定时执行) -- 查看当前mysql数据库是否开启时间功能,默认关闭SHOW VARIABLES LIKE 'event_scheduler'; -- event_schedule ...
- IDEA -14 注册码生成工具
import java.math.BigInteger; import java.util.Date; import java.util.Random; import java.util.zip.CR ...
- P2680 运输计划
http://www.luogu.org/problem/show?pid=2680#sub 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航 ...
- php获取 本月 本周 或者 下月 下周的 开始时间 结束时间
<?php $now_time = time(); $date=date("Y-m-d",$now_time); function get_date($date,$t='d' ...