1、说说概念面试
1、进程(process)编程
狭义定义:进程就是一段程序的执行过程。安全
广义定义:进程是一个具备必定独立功能的程序关于某个数据集合的一次运行活动。它是操做系统动态执行的基本单元,在传统的操做系统中,进程既是基本的分配单元,也是基本的执行单元。多线程
简单的来说进程的概念主要有两点:第一,进程是一个实体。每个进程都有它本身的地址空间,通常状况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,咱们称其为进程。并发
进程状态:进程有三个状态,就绪、运行和阻塞。就绪状态其实就是获取了出cpu外的全部资源,只要处理器分配资源就能够立刻执行。就绪状态有排队序列什么的,排队原则再也不赘述。运行态就是得到了处理器分配的资源,程序开始执行。阻塞态,当程序条件不够时候,须要等待条件知足时候才能执行,如等待i/o操做时候,此刻的状态就叫阻塞态。异步
2、程序ide
提及进程,就不得不说下程序。先看定义:程序是指令和数据的有序集合,其自己没有任何运行的含义,是一个静态的概念。而进程则是在处理机上的一次执行过程,它是一个动态的概念。这个不难理解,其实进程是包含程序的,进程的执行离不开程序,进程中的文本区域就是代码区,也就是程序。spa
3、线程操作系统
一般在一个进程中能够包含若干个线程,固然一个进程中至少有一个线程,否则没有存在的意义。线程能够利用进程所拥有的资源,在引入线程的操做系统中,一般都是把进程做为分配资源的基本单位,而把线程做为独立运行和独立调度的基本单位,因为线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提升系统多个程序间并发执行的程度。线程
4、多线程
在一个程序中,这些独立运行的程序片断叫做“线程”(Thread),利用它编程的概念就叫做“多线程处理”。多线程是为了同步完成多项任务,不是为了提升运行效率,而是为了提升资源使用效率来提升系统的效率。线程是在同一时间须要完成多项任务的时候实现的。
最简单的比喻多线程就像火车的每一节车箱,而进程则是火车。车箱离开火车是没法跑动的,同理火车也不可能只有一节车箱。多线程的出现就是为了提升效率。
2、说说区别
1、进程与线程的区别:
进程和线程的主要差异在于它们是不一样的操做系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不一样执行路径。线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。
1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
2) 线程的划分尺度小于进程,使得多线程程序的并发性高。
3) 另外,进程在执行过程当中拥有独立的内存单元,而多个线程共享内存,从而极大地提升了程序的运行效率。
4) 线程在执行过程当中与进程仍是有区别的。每一个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。可是线程不可以独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分能够同时执行。但操做系统并无将多个线程看作多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
3、说说优缺点
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP(多核处理机)机器上运行,而进程则能够跨机器迁移。
4、总结
入职第一天闲的无聊,参考下别人的总结本身也简单总结了下。知道以上的基本面试够用了,至于进程、线程的细节,底层构成,调度等问题是操做系统的东西。我就不详述了。
5、实例
一、多线程写日志,涉及到单例模式,异步写
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Thread t1 = new Thread(Working); t1.Name = "Thread1"; Thread t2 = new Thread(Working); t2.Name = "Thread2"; Thread t3 = new Thread(Working); t3.Name = "Thread3"; // 依次启动3个线程。 t1.Start(); t2.Start(); t3.Start(); Console.ReadKey(); } // 每一个线程都同时在工做 static void Working() { // 模拟1000次写日志操做 for (int i = 0; i < 1000; i++) { // 异步写文件 logger.Write(Thread.CurrentThread.Name + " writes a log: " + i + ", on " + DateTime.Now.ToString() + ".\n"); }// 作一些其它的事件 for (int i = 0; i < 100; i++) { } } } public class logger { private Queue<Action> _queue; //写日志线程 private Thread _loggingThread; //信号器 private ManualResetEvent _hasNew; // 使用单例模式,保持一个Logger对象 private static readonly logger _logger = new logger(); private static logger GetInstance() { /* 不安全代码 lock (locker) { if (_logger == null) { _logger = new Logger(); } }*/ return _logger; } private logger() { _queue = new Queue<Action>(); _hasNew = new ManualResetEvent(false); _loggingThread = new Thread(Process); _loggingThread.IsBackground = true; _loggingThread.Start(); } private void Process() { while (true) { //等待信号,阻塞线程 _hasNew.WaitOne(); //接收到信号,信号关闭,重置 _hasNew.Reset(); Thread.Sleep(100); Queue<Action> queueCopy; lock (_queue) { queueCopy = new Queue<Action>(_queue); _queue.Clear(); } foreach (var action in queueCopy) { action(); } } } private void WeiteLog(string content) { lock (_queue) { _queue.Enqueue(() => File.AppendAllText("log.txt", content)); } _hasNew.Set(); } public static void Write(string content) { Task.Run(() => GetInstance().WeiteLog(content)); } } }