1.线程的用户模式栈——对于本地应用程序,windows会预定1MB内存的地址空间。但这仅仅是一个虚拟地址空间,并没有对应的物理存储。只有在以后真正需要的时候,才会实际提交物理内存。
然而当托管应用程序创建一个线程时,clr强迫windows立即预定地址空间并完全提交栈的物理空间。
必须承认,今天系统中的大多数线程是由本地(native)代码创建的。所以,线程的用户模式栈仅仅是预定地址空间,而且栈既有可能并没有完全提交(fully committed)来获取物理内存。然而随着越来越多的应用程序成为托管应用程序,或者在其中运行托管组件(outlook就支持这样做),会有越来越多的栈完全提交。会实打实地分配到完整的1mb物理存储。无论如何,即使抛开用户模式不谈,所有线程也仍然会分配到一个内核对象、TEB(thread environment block)、内核模式栈以及其他资源。
0626
2.
UI需要得到大幅精简。做到自动化
上下文(context)反映了当前线程上一次执行时,线程的cpu寄存器的状态。
在一个时间片(time slice) 之后,windows检查所有线程内核对象。只有那些没有等待什么的线程才适合调度(可调度线程)。Microsoft spy++:查看调度次数(type 'spy' for searching)
Base Priority
Context Switches:线程上下文切换次数。
Elapsed Time:表示该线程已经在系统存在了这么多时间,但是只执行了CPU Time。
thread state:wait.表示该线程没有执行,在等待发生某个输入或输出操作。
windows之所以被称为抢占式多线程(preemptive multithread)操作系统,是因为线程可以在任何时间停止(被抢占),并调度另一个线程。
线程优先级0-31,只要存在可以调度的优先级31的线程,系统就永远不会将优先级0-30的任何线程分配给cpu——饥饿(starvation)。
进程优先级类(priority class)和线程相对优先级。启进程,调度线程。
clr保留了idle和time-critical两个等级,所以枚举值ThreadPriority只有5个值。
0627
计算限制操作和I/O限制操作
clr初始化时,线程池中是没有线程的。在内部,线程池维护了一个操作请求队列(存放线程方法)。线程池从这个队列中提取entry,dispatch给某个线程。
刚开始是没有线程的,所以先创建一个线程(有一定的性能损失)。但是当线程完成任务后,不会被销毁。相反,会返回线程池,在那里进入空闲状态,等待响应另一个请求。由于线程不销毁自身,所以不再产生额外的性能损失。
当一个线程闲着没事干一段时间后,线程会自己醒来终止自己以释放资源。
阻止执行上下文的流动,可以提升性能。
0630
System.Threading.Timer,定时让一个线程池线程调用方法。
线程池默认最大线程数1000.因为一个32位的进程最大拥有2gb的内存地址空间。加载了一组win32和clr dlls,并分配了本地堆和托管堆之后,剩余约1.5gb的地址空间。
由于每个线程都要为其用户模式栈和线程环境块(TEB)准备超过1MB的内存,所以在一个32位的进程中,最多能够拥有1360个线程。
线程首次从RAM读取一些值时,cpu从RAM获取所需的值,并把它存储到cpu的高速缓存中。为了进一步提升性能,cpu会在逻辑上将所有的内存划分为为所谓的缓冲航(cache line)。对于我的cpu,一个缓冲行占64个字节,所以cpu从RAM中获取并存储64字节的块。例如,如果应用程序 要读取一个Int32的值,那么会获取包含Int32的64个字节。
获取比需要的更多的字节,通常会带来性能增加,因为大多数应用程序在访问了一些数据后,通常会继续访问那些数据周围的其他数据。
0702
应用程序模型有他自己的线程处理模式
一个SynchronizationContext派生对象负责将一个应用程序模型连接到它的线程处理模式。
public class SynchronizationContext
{
public static SynchronizationContext Current{ get; }
public virtual void Post(SendOrPostCallback d,object state)//异步调用
public virtual void Send(SendOrPostCallback d,object state)//同步调用
}
//
public delegate SendOrPostCallback(object state);
public AsyncCallback SyncContextCallback(AsyncCallback)
{
SynchronizationContext sc = SynchronizationContext.Current;
if(sc==null){return callback;}
return asyncResult = >sc.Post(result=>callback((IAsyncResult)result),asyncResult);
}