当前位置: 首页 > news >正文

连云港企业做网站将制作好的网站上传去因特网

连云港企业做网站,将制作好的网站上传去因特网,校友网站建设的重要性,怎样做淘宝网站线程池(ThreadPool)使用起来很简单#xff0c;但它有一些限制#xff1a; 1. 线程池中所有线程都是后台线程#xff0c;如果进程的所有前台线程都结束了#xff0c;所有的后台线程就会停止。不能把入池的线程改为前台线 程。 2. 不能给入池的线程设置优先级或名称。 3. 对于…  线程池(ThreadPool)使用起来很简单但它有一些限制 1. 线程池中所有线程都是后台线程如果进程的所有前台线程都结束了所有的后台线程就会停止。不能把入池的线程改为前台线 程。 2. 不能给入池的线程设置优先级或名称。 3. 对于COM对象入池的所有线程都是多线程单元(Multi-threaded apartment,MTA)线程。许多COM对象都需要单线程单元(Single -threaded apartment,STA)线程。 4.入池的线程只能用于时间较短的任务。如果线程要一直运行(如Word的拼写检查器线程),就应使用Thread类创建一个线程。 高效线程使用圣典 严格来讲线程的系统开销很大。系统必须为线程分配并初始化一个线程内核对象还必须为每个线程保留1mb的地址空间 按需提交用于线程的用户模式堆栈分配12kb左右的地址空间用于线程的内核模式堆栈。然后紧接着线程创建后windows调 用进程中每个dll都有的一个函数来通知进程中所有的dll操作系统创建了一个新的线程。同样销毁一个线程的开销也不小进程 中的每个dll都要接收一个关于线程即将“死亡”的通知而且内核对象及堆栈还需释放。 如果一台计算机中只有一个cpu那么在某一时刻只有一个线程可以运行。windows必须跟踪记录线程对象而且是不停地跟 踪记录每个线程对象。windows不得不决定cpu下次调度哪个线程来执行。这个额外的代码不得不每隔20ms左右执行一次。windows使 cpu停止执行一个线程的代码而开始执行另一个线程的代码的现象我们称之为上下文切换context switch。上下文切换的开 销相当大因为操作系统必须执行以下步骤 1. 进入内核模式。 2. 将cpu的寄存器保存到当前正在执行的线程的内核对象中。x86架构的机器上cpu寄存器占了大约700字节的空间x64架构 的机器上cpu寄存器占了大约1240字节的空间而在ia64架构的机器上cpu寄存器占了大约2500字节的空间。 3. 需要一个自旋锁spin lock确定下一次调度哪个线程然后再释放该自旋锁。如果下一次调度的线程属于另一个进 程那么此处的开销会更大因为操作系统必切换到虚拟地址空间。 4. 将即将运行的线程的内核对象的值加载到cpu寄存器中。 5. 退出内核模式。 所有上述内容都是纯粹的开销导致windows操作系统和应用程序的执行速度比在单线程系统上的执行速度慢。 综合上述所有结果可得出以下结论应尽可能地限制线程的使用。如果创建的线程越多给操作系统带来的开销就越大所 有的东西也就运行得越慢。另外每个线程都需要资源内核对象占用的内存及两个堆栈所以每个线程都会消耗内存。 线程还有另一个用途可扩展性。当计算机有多个cpu时windows能同时调度多个线程每个cpu运行一个线程。 CLR线程池简介 如前所述创建并销毁一个线程在时间上的开销相当大。另外线程多还会浪费内存资源而且由于操作系统不得不在可运 行线程间进行调度和上下文切换从而影响操作系统和应用程序的性能。为改进这种现象clr中包含管理clr线程池的代码。我们 可以将线程池看作应用程序自己使用的线程的集合。每个进程都有一个线程池这个线程池被该进程中的所有应用程序域共享。 当clr初始化时线程池中还没有任何线程。从内部实现上讲线程池维护了一系列操作请求。应用程序希望执行一个异步 操作时可以调用一些方法在线程池的队列中加入一个条目。线程池中的代码将从这个队列中提取出条目并将该条目分派到线程 池中的线程。如果线程池中没有任何线程就创建一个新的线程。创建一个线程会有相关的性能损失。但是当线程池中的线程完 成任务时并不会被销毁而是返回到线程池中在线程池中空闲等待响应另外的请求。因为线程不对它自身进行销毁所以此 处不会带来性能损失。 如果应用程序对线程池进行了很多的请求那么线程池将试图只用一个线程来响应所有的请求。但是如果应用程序排队的 请求超出了线程池的处理能力线程池中将创建另外的线程。最终应用程序排队的请求与线程池中线程的处理能力达到一个平衡 点我们可以采用较小数量的线程来处理所有的请求因此线程池中也就不再需要创建更多的线程。 如果应用程序停止请求线程池线程池中可能会有许多不做事情的线程。这种情况会浪费内存资源。因此当线程池中的线 程空闲超过大约2分钟后线程将唤醒自己并终止自己以释放内存资源。当线程终止自己时也会存在一个性能损失。但是该 性能损失不是很严重因为线程在终止自己时线程已处于空闲状态这意味着我们的应用程序当前没有执行太多的工作。 从内部实现上讲线程池将线程池中的线程进行分类划分为工作线程worker thread和i/o线程i/o thread。当应 用程序请求线程池执行一个受计算限制的异步操作包括初始化受i/o限制的异步操作时使用工作线程而i/o线程用于在受i/o限 制的异步操作完成时通知代码。具体而言这意味着我们需要使用异步编程模型来进行i/o请求。 限制线程池中的线程数量 clr的线程池允许开发人员设置工作线程和i/o线程的最大数量。clr保证创建的线程数量不会超过这个设置值。但永远不要 对线程池中线程的数量设置一个上限因为饥饿和死锁现象可能会发生。在clr的2.0版默认中工作线程的默认最大数量为机器中 每个cpu25个i/o线程最大数量设为1000个。 system.threading.threadpool类提供了几个操作线程池中线程数量的静态方法getmaxthreads查询线程池对线程数量的 最大限制、setmax-threads设置线程数量最大限制、getminthreads查询线程池对线程数量的最小限制、setminthreads 设置线程数量最小限制、getavailable-threads。 强烈建议不要调用setmaxthreads方法修改线程池中线程数量的限制因为这会导致损害应用程序的执行性能。 clr的线程池试图避免过快地创建额外的线程。具体而言线程池试图避免每隔500ms就创建一个新的线程。这对某些开发人 员而言引发了一个问题因为队列中的任务无法得到及时地处理。要处理此问题可以调用setminthreads方法设置线程池中拥有 线程的最低数量。调用该方法后线程池将很快地创建这么多的线程并且当队列的任务继续增加所创建的所有线程都被使用后 线程池还会按照每隔500ms的时间继续创建额外的线程。默认情况下线程池中工作线程和i/o线程的最小数量被设为2这个值可 以通过调用getminthreads方法获得。 最后可以通过调用getavailablethreads方法来获得线程池中可以增加的额外线程的数量。该方法的返回值为线程池中可 以拥有的线程的最大数量减去线程池中当前所拥有的线程数量。这个值仅在返回的那一刻有用因为在方法返回后线程池中可能 已经增加了许多线程或有些线程可能已被销毁。 使用线程池执行受计算限制的异步操作 受计算限制的操作是需要进行计算的操作。如电子表格应用程序中可计算的单元。理想情况下受计算限制的操作不会执 行任何异步i/o操作因为所有的异步i/o操作在底层硬件执行工作时都将挂起调用线程。应该尽量使线程运行因为挂起的线程不 再继续运行但仍然使用系统的资源。 为了将一个受计算限制的异步操作加入到线程池的队列中一般可以使用threadpool类中定义的下述方法   static bool QueueUserWorkItem(WaitCallback callback);static bool QueueUserWorkItem(WaitCallback callback, object state);static bool UnsafeQueueUserWorkItem(WaitCallback callback, object state); 上述方法将一个“工作项”及可选的状态数据加入到线程池的队列中然后这些方法就会立即返回。工作项仅仅是一个 由callback参数标识的方法线程池中的线程将调用该方法。该方法可以只传递一个单独的由state状态数据参数指定的参数。 没有state参数的QueueUserWorkItem方法为回调函数传递null。最终线程池中的一些线程将执行工作项从而导致我们的方法被 调用。我们写的回调方法必须匹配system.threading.WaitCallback委托类型它的定义方式如下所示 delegate void WaitCallback(object state); 下面的代码演示了线程池中的线程如何异步调用一个方法   using system;using system.threading;public static class program {public static void main() { console.writeline(main thread: queuing an asynchronous operation); threadpool.QueueUserWorkItem(computeboundop, 5); console.writeline(main thread: doing other work here ...); thread.sleep(10000); //模拟其他工作10秒钟console.writeline(hit enter to end this program ...); console.readline(); }//该方法的签名必须与WaitCallback委托类型匹配private static void computeboundop(object state) { //该方法由线程池中的线程执行console.writeline(in computeboundop: state{0}, state); thread.sleep(1000); //模拟其他工作1秒钟//在该方法返回后线程就回到线程池中然后等待执行另一个任务} } 如果回调方法抛出的异常是未处理异常那么clr将终止进程。 threadpool类有一个UnsafeQueueUserWorkItem方法。该方法与平时调用的QueueUserWorkItem方法非常相似。下面先简单介 绍一下这两个方法的区别试图访问一个受限资源如打开一个文件时clr将执行一个代码访问安全code access security cas检查。也就是说clr将检查调用线程的调用堆栈中的所有程序集是否都有访问资源的许可权限。如果有一些程序集没有所需 的许可权限clr将抛出一个securityexception异常。假设正在执行代码的线程所在的程序集没有打开文件的许可权限那么在线 程试图打开文件时clr将抛出一个securityexception异常。 为让线程继续运行线程可以在线程池的队列加入一个工作项让线程池中的线程来执行打开文件的代码。当然这必须在拥 有合适许可权限的程序集中进行。这种“工作区”智取安全权限的现象可以允许怀恶意的代码对受限资源进行严重破坏。为阻止这 种获得安全权限的方式QueueUserWorkItem方法内部遍历调用线程的堆栈并捕获所有被授予的安全权限。然后当线程池中的线 程开始执行时这些权限再与线程结合。因此线程池中的线程以调用QueueUserWorkItem方法的线程相同的权限集来完成运行。 遍历线程的堆栈并捕获所有的安全权限与性能紧密相关。如果希望改进受计算限制的异步操作的排队性能可以调用 UnsafeQueueUserWorkItem方法。该方法只将工作项加入到线程池的队列中而不遍历调用线程的堆栈。最后结果是这个方法比 QueueUserWorkItem方法执行得快但它在应用程序中打开了一个潜在的安全漏洞。仅当可以确认线程池中的线程执行的代码不触及 受限资源时或确信接触这部分资源不会出现问题时我们才可以调用unsafequeueuserwork-item方法。同样还需注意调用该方 法需要使securitypermission的controlpolicy标记和controlevidence标记开启可阻止未信任的代码偶然或故意提升它的许可权 限。 使用专用线程执行受计算限制的异步操作 强烈建议大家尽量多用线程池来执行受计算限制的异步操作。但在有些情况下我们可能希望显式创建一个线程专门用于 执行特定的受计算限制的异步操作。一般情况下如果即将执行的代码需要线程处于一个特定的状态与线程池中线程的普通状态 不同那么就希望创建一个专用的线程。如希望线程以一个特殊的优先级运行所有线程池中的线程都以普通优先级运行而 且我们不应该修改线程池中线程的优先级就需要创建一个专用的线程。再如希望让一个线程成为前台线程所有线程中的线 程都是后台线程也可以考虑创建并使用自己的线程从而阻止应用程序的“死亡”直到线程完成任务。如果受计算限制的任 务运行的时间特别长也应该使用专用线程这样我们就不必让线程池的逻辑去费力判断是否还需创建额外的线程。最后如果 我们希望启动一个线程然后通过调用thread的abort方法中断该线程的话应该使用一个专用线程。 为创建一个专用线程我们可构建一个system.threading.thread类的实例以方法的名称作为构造器的参数。下面是构 造器的原型   public sealed class thread : criticalfinalizerobject, ... {public thread(parameterizedthreadstart start); } 参数start用来标识专用线程的方法即将执行这个方法必须与委托parameterizedthreadstart的签名相匹配   delegate void parameterizedthreadstart(object obj); 可看出parameterizedthreadstart委托的签名与WaitCallback委托的签名相同。这意味着使用一个线程池中的线程或使用 一个专用线程就可以调用相同的方法。 构建一个thread对象并不创建一个操作系统线程。为实际创建一个操作系统线程并让它开始执行回调方法我们必须调用 thread的start方法。如下所示   using system;using system.threading;public static class program {public static void main() { console.writeline(main thread: starting a dedicated thread to do an asynchronous operation); thread dedicatedthread new thread(computeboundop); dedicatedthread.start(5); console.writeline(main thread: doing other work here...); thread.sleep(10000); //模拟其他工作10秒 dedicatedthread.join(); //等待线程终止 console.writeline(hit enter to end this program...); console.readline(); }//该方法的签名必须与parameterizedthreadstart委托匹配private static void computeboundop(object state) { //该方法由一个专用线程执行console.writeline(in computeboundop: state {0}, state); thread.sleep(1000); //模拟其他工作1秒} } 注意main方法调用了join方法而join方法导致调用线程停止执行任何代码直到由dedicatedthread标识的线程自己销 毁自己或被终止。使用threadpool的QueueUserWorkItem方法将异步操作排队时clr没有提供内置的方法来判断操作是否完成。而 join方法却在我们使用专用线程时为我们提供了这种能力。但是如果需要知道操作是在什么时候完成的就不应该使用专用线程 来取代QueueUserWorkItem方法而应该使用apm。 转载文章C/S框架网责任编辑
http://www.pierceye.com/news/211828/

相关文章:

  • 宁夏住房城乡建设厅网站应用网站建设
  • 宾馆网站建设网站建设管理规范
  • 内部网站建设的步骤过程选择邯郸做网站
  • 国外免费外贸网站dw网页制作教程个人网站
  • 西安建设局网站地址室内设计效果图一套方案
  • php 建网站电子商务网站建设项目规划书
  • 常熟建设局网站代理办营业执照的公司
  • 济南网站关键词优化公司如何制作网站赚钱
  • 长春旅游网站开发360投放广告怎么收费
  • 微信公众号做网站卖东西静态化网站的缺点
  • 网站空间购买今天的新闻头条最新消息
  • 网站制作教程图解怎么解压wordpress
  • 唐山市城市建设规划局网站腾讯云建设一个网站要多少钱
  • 邢台集团网站建设费用聚牛建设网站
  • 如何创建电子商务网站学校网站设计首页
  • 扬州建设投资集团网站世界总人口实时数据
  • 沧州制作网站食品商务网-网站建设
  • 0592 网站建设模板网站建设+百度
  • 请人做个网站多少钱免费商城app
  • 网站建设包括哪些方面?手游源码网站
  • 机关门户网站建设管理情况软件开发工具都有哪些
  • 官方网站建设专家磐石网络wordpress对应的id
  • 学生自做网站优秀作品徐州企业建站模板
  • 网络电子商务购物网站idc机房建设
  • 网站单页seo个人服务器网站备案
  • 装修队伍做网站做机票在线预订网站
  • 手机版企业网站php山西建设执业注册中心网站
  • 南充网站建设略奥科技凡科建站电话
  • 个人网站可以做自媒体吗手机网站建设需要多少钱
  • 网站 模板网站什么英文字体