线程

线程也被称为轻量级进程lightweight process ,LWP,线程是CPU独立调度和分派的基本单位,同一个进程中的多个线程将共享该进程中的全部系统资源,多线程共享堆heap资源,c#程序默认有一个主线程,**辅助线程 worker thread **,与主线程一起执行任务,辅助线程主要做计算操作,IO线程主要做输入输出的操作

进程

process进程类,程序与进程没有一一对应关系,进程是程序在计算机市的一次执行活动,进程可以分为用户进程系统进程,进程可以分为用户进程和系统进程,同一个进程中的uoge线程有各自的调用栈(call stack),自己的寄存器环境(register context)

进程与线程的关系

进程与线程池关系:每个进程一个线程池ThreadPool

单线程

只有一个线程的程序,什么时候用单线程比较好:计算密集型的操作,因为CPU的分片操作会浪费计算时间,一次算完比较快

多线程

线程池

为什么会有线程池?为了优化线程创建和销毁的资源消耗,创建和销毁影响程序性能

LOCK

lock(x),x需要是一个对象, 是全局变量

首先要明白为什么上面这段话能够锁定代码,其中的奥妙就是X这个对象,事实上X是任意一种引用类型,它在这儿起的作用就是任何线程执行到lock(X)时候,X需要独享才能运行下面的代码,若假定现在有3个线程A,B,C都执行到了lock(X)而ABC因为此时都占有X,这时ABC就要停下来排个队,一个一个使用X,从而起到在下面的代码块内只有一个线程在运行(因为此时只有一个线程独享X,其余两个在排队),所以这个X必须是所有要执行临界区域代码进程必须共有的一个资源,从而起到抑制线程的作用。

lock关键字可以用来确保代码块完成运行而不被其他线程中断。语句以lock开头,在参数后面还有一个只能由一个线程执行的代码块。

lock 是一个语法糖,lock等于monitor+异常处理,lock=安全的monitor,lock关键字就是用monitor类来实现的

Monitor类

1.Monitor类可以防止多个线程同时执行代码块

2.Monitor方法允许一个且仅一个线程继续执行后面的语句,其他所有线程都将被阻止,直到执行语句的线程调用Exit

3.这与使用lock关键字一样,事实上,lock关键字就是用monitor类来实现的

Object ss= new Object();

Monitor.Enter(ss);

try { // 需要执行的代码 }

finally{ Monitor.Exit(ss);} // 退出线程锁定

waitHandle.waitone

waitHandle.waitany

waitHandle.waitall

创建线程 Thread ThreadStart

 class Program
{
const int res = 1000;
static void Main(string[] args)
{
ThreadStart threadstart = DoWork;
Thread thread = new Thread(threadstart);
thread.Start();
for (int i = 0; i < res; i++)
{
Console.Write("-");
}
thread.Join(); //
Console.ReadKey();
}
static void DoWork()
{
for (int i = 0; i < res; i++)
{
Console.Write("+");
}
}
//1.其中thread.Join()方法会造成当前进程(主进程)等待,直到其他正在执行的进程结束
//2.thread.IsBackGround = true; 将当前进程设置为后台进程
//3.thread.Priority = ThreadPriority.Highest ; 将进程的优先级设置为最高级(当然还有其他枚举值)
//4.Console.WriteLine(thread.ThreadState) 输出当前进程的状态 /////////////////////////////////////////////////////////////////////////////////////////
public static void CallToChildThread()
{
Console.WriteLine("Child thread starts");
}
public static void CallToParentThread()
{
Console.WriteLine("Parent thread starts");
}
static void Main(string[] args)
{
ThreadStart childref = new ThreadStart(CallToChildThread); // 创建线程的委托,并将需要调用的方法赋给委托
childref += CallToParentThread; // 赋值新的方法给委托
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Console.ReadKey();
}

锁定线程

        class Program
{
static List<int> numbers = new List<int>();
static object locker = new object();
static void Main(string[] args)
{
numbers.Add(0);
Thread t1 = new Thread(GetNum);
t1.Start();
Thread t2 = new Thread(SetNum);
t2.Start();
Console.ReadKey();
}
static void GetNum()
{
lock (locker)
{
Console.WriteLine("t1->" + numbers[0]); // -> 0
Thread.Sleep(1000);
Console.WriteLine("t1->" + numbers[0]); // -> 0
}
}
static void SetNum()
{
lock (locker)
{
numbers[0] = 2;
Console.WriteLine("t2->" + numbers[0]); // ->2
}
}
}
}

管理线程 Thread.Sleep()

            Console.WriteLine("this is a sleep function test");
Thread.Sleep(5000);
Console.WriteLine("this is new thread function");
//注意:避免在正式的生产代码中使用Sleep()函数
//1.没有参数就是没有延迟时间设置,相当于没有写
//2.使用sleep(时间设定值)来同步的程序被成为”穷人的同步“

终止线程 Thread.Abort()

            ThreadStart ts = new ThreadStart(Speak);

            Thread aa = new Thread(ts);
aa.Start();
aa.Abort();
ts += Speak2;
aa.Start(); // 这个会报错,因为已经被终止的线程无法再开启 // 注意:避免在正式的生产代码中使用Abort()函数,因为可能造成不可预测的结果,造成程序不稳定

ThreadPool线程池

如果池中的现场都被长时间运行或者I/O受限的工作占用了,正在排队的工作必然会延迟。所以在高性能程序设计的时候,这个ThreadPool和Thread只作为实现细节使用

        const int res = 1000;
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(DoWork,"sss"); // 可以加个逗号传参数进去
for (int i = 0; i < res; i++)
{
Console.Write("-");
}
Console.ReadKey();
}
static void DoWork(object ss) // 方法的参数必须是一个,且只能是可以转换为object的类型
{
for (int i = 0; i < res; i++)
{
Console.Write("+");
}
}

TPL ( Task Parallel Library ) 任务并行库

有长时间运行或者I/O受限的工作的需求时,使用TPL构建高级抽象。

1.TPL提供了一个能代表异步工作的对象,还提供了相应的API以便与工作进行交互。

(类比委托,委托封装了方法,但它是同步的)

Task

Task.Run方法

Task.Wait方法

            Task tt = Task.Run(
() =>
{
for (int count = 0; count < res; count++)
{
Console.Write("-");
}
}
);
tt.Wait(); // 当前线程等待tt线程结束后再执行
// Task.WaitAll(tt); // 另一种写法
for (int i = 0; i < res; i++)
{
Console.Write("+");
}
Console.ReadKey();

Task.ContiuneWith()方法

            Console.WriteLine("Before");
Task task1 = Task.Run(
() => { Console.WriteLine("Start with ....."); }
).ContinueWith((a) => { Console.WriteLine("continuing A ....."); }); // 这里面的的a其实是Task a,大概是方便lambda内部的函数调用吧
Task task2 = task1.ContinueWith(
(a) => { Console.WriteLine("continuing B ....."); }
);
Task task3 = task1.ContinueWith(
(a) => { Console.WriteLine("continuing C ....."); }
);
Task.WaitAll(task2, task3);
Console.WriteLine("Finsihed");
Console.ReadKey();

AppDomain (这个CLR VIA C#中有详细讲解,不过现在看不懂)

1.一个AppDomain中的代码创建的对象不能由另一个AppDomain中的代码直接访问

2.AppDomain可以卸载

3.AppDomain可以单独保护。AppDomain在创建后,会应用一个权限集,它决定了在这个AppDomain中运行的程序集的最大权限

4.AppDomain可以单独实施配置。AppDomain在创建后,会关联一组配置设置。这些设置主要影响CLR在AppDomain中加载程序集的方式。这些设置涉及搜索路径,版本绑定重定向,卷影复制及加载器优化

AppDomain vs 进程

AppDomain被创建在进程中,一个进程内可以有多个AppDomain。一个AppDomain只能属于一个进程。

2.AppDomain vs 线程

其实两者本来没什么好对比的。AppDomain是个静态概念,只是限定了对象的边界;线程是个动态概念,它可以运行在不同的AppDomain

C#--进程-线程的更多相关文章

  1. python学习笔记-进程线程

    1.什么是进程(process)? 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述 ...

  2. 获取系统中所有进程&线程信息

    读书笔记--[计算机病毒解密与对抗] 目录: 遍历进程&线程程序 终止进程 获取进程信息 获取进程内模块信息 获取进程命令行参数 代码运行环境:Win7 x64 VS2012 Update3 ...

  3. [skill] 进程 线程

    在业务逻辑上: 进程线程没有区别. 在系统资源上: 进程拥有自己的地址空间.线程拥有自己的堆栈和临时变量,与其他线程共享地址空间. 在通信代价上: 线程间通信代价更低,实现更方便.进程通信相对开销比较 ...

  4. pyhon——进程线程、与协程基础概述

    一直以来写博客都是实用主义者,只写用法,没信心写原理,但是每一次写作业的过程都有一种掘地三尺的感觉,终于,写博客困难症重症患者经历了漫长的思想斗争,还是决定把从网上淘到的各种杂货和自己的总结放在一起, ...

  5. android 进程/线程管理(一)----消息机制的框架

    一:android 进程和线程 进程是程序运行的一个实例.android通过4大主件,弱化了进程的概念,尤其是在app层面,基本不需要关系进程间的通信等问题. 但是程序的本质没有变,尤其是多任务系统, ...

  6. android 进程/线程管理(二)----关于线程的迷思

    一:进程和线程的由来 进程是计算机科技发展的过程的产物. 最早计算机发明出来,是为了解决数学计算而发明的.每解决一个问题,就要打纸带,也就是打点. 后来人们发现可以批量的设置命令,由计算机读取这些命令 ...

  7. android 进程/线程管理(三)----Thread,Looper / HandlerThread / IntentService

    Thread,Looper的组合是非常常见的组合方式. Looper可以是和线程绑定的,或者是main looper的一个引用. 下面看看具体app层的使用. 首先定义thread: package ...

  8. android 进程/线程管理(四)续----消息机制的思考(自定义消息机制)

    继续分析handler 和looper 先看看handler的 public void dispatchMessage(Message msg) { if (msg.callback != null) ...

  9. android 进程/线程管理(四)----消息机制的思考(自定义消息机制)

    关于android消息机制 已经写了3篇文章了,想要结束这个系列,总觉得少了点什么? 于是我就在想,android为什么要这个设计消息机制,使用消息机制是现在操作系统基本都会有的特点. 可是andro ...

  10. windows进程/线程创建过程 --- windows操作系统学习

    有了之前的对进程和线程对象的学习的铺垫后,我们现在可以开始学习windows下的进程创建过程了,我将尝试着从源代码的层次来分析在windows下创建一个进程都要涉及到哪些步骤,都要涉及到哪些数据结构. ...

随机推荐

  1. ext4文件系统制作 - make_ext4fs 参数介绍【转】

    本文转载自:http://blog.csdn.net/u011784994/article/details/53816976 make_ext4fs用于Android平台上制作ext4文件系统的镜像. ...

  2. C++中的inline的用法

    C++中的inline的用法  参考:http://www.cnblogs.com/fnlingnzb-learner/p/6423917.html 1. 引入inline关键字的原因 在c/c++中 ...

  3. RMAN 备份与恢复 实例

    1. 检查数据库模式:    sqlplus /nolog     conn /as sysdba    archive log list (查看数据库是否处于归档模式中) 若为非归档,则修改数据库归 ...

  4. 3.3 文件I/O

    错误的解决方法请参考:http://liangruijun.blog.51cto.com/3061169/673776 3.3.2 访问手机中的存储文件夹 3.3.3 读取assets中的文件 pac ...

  5. [Apple开发者帐户帮助]六、配置应用服务(2)创建DeviceCheck私钥

    要验证与DeviceCheck服务的通信,您将使用启用了DeviceCheck的私钥. 首先创建并下载启用了DeviceCheck 的私钥.然后获取密钥标识符(kid)以创建JSON Web令牌(JW ...

  6. jdbc 接口学习笔记

    一.JDBC概念 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它由一组用Jav ...

  7. js-内置对象及相关语法

    1:如图(视频截取的) this指的是当前标签的对象. var ary=new Array("mark","jay","leslie"); ...

  8. DOM高级编程

    前言:W3C规定的三类DOM标准接口(换图)Core DOM(核心DOM),适用于各种结构化文档:XML DOM(Java OOP学过),专用于XML文档:HTML DOM,专用于HTML文档,下面了 ...

  9. selenium有多个窗口时操作某个窗口的内容

    这个页面点击html/css后会弹出一个新的窗口,此时要操作新的窗口的内容,使用switchTo 跳转代码 driver.get("https://www.imooc.com"); ...

  10. uni-app的专属强大自适应单位upx,但是这个这是一个大坑,不能动态赋值解决办法

    uni-app 使用 upx 作为默认尺寸单位, upx 是相对于基准宽度的单位,可以根据屏幕宽度进行自适应.uni-app 规定屏幕基准宽度750upx. 开发者可以通过设计稿基准宽度计算页面元素 ...