线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。
使用ThreadPool来访问线程池
这种做法可以让我们不用那么复杂的去实现创建,重用线程的逻辑,但是也有一些限制,比如由他内置的方法,我们不知道什么时候线程池里面的任务会结束,也不能获取线程的返回值。为了解决这些问题,微软引入了一个新的概念。
使用Task来访问线程池
引入了Task之后,你可以用如下实现来替代ThreadPool
这些实现都是等价的。Task本身实现了很多ThreadPool不能做的事情。
使用Task来获得线程的返回值
使用Task来等待线程结束
更多Task同步编程的使用,请参见(还没写,先给自己挖个坑O(∩_∩)O)。
异步委托
ThreadPool.QueueUserWorkItem没有提供一种简单的机制来获取线程的返回值。异步委托解决了这个问题,支持了传入一系列的参数。此外,异步委托中没有处理的异常会很方便的在调用线程的重新抛出(在调用EndInvoke的时候),因此不需要显示的处理。
通过异步委托来执行任务主要分一下几步:
-
初始化并声明一个你想要执行的委托 -
在委托上调用BeginInvoke,把返回值保存为IAsyncResult中
调用BeginInvoke不会阻塞当前线程,因此你可以在调用完之后执行其他你想要同步的操作
-
当你需要获取委托的返回值时,调用EndInvoke方法,把IAsyncResult传入EndInvoke中
阻塞的方式执行异步委托
EndInvoke主要做3件事: 1. 等待异步委托完成 2. 接收返回值 3. 把异步线程中未处理的异常在当前线程中重新抛出。
非阻塞的方式执行异步委托
你也可以在调用BeginInvoke的时候指定一个回调方法,这个方法会在异步委托结束的时候自动调用。这样异步委托就像是一个后台线程一样自动执行,不需要主线程等待。只需要在BeginInvoke的时候做一些额外的操作即可实现这种操作。
关于线程池
Jeffery在C# via CLR Chapter27中针对线程池的使用给出了一些建议。目前我们允许开发者来指定一个线程池的最大线程数。但是事实证明,我们往往不应该为一个线程池指定线程的上限,否则可能会出现程序死锁或者饿死的状态。比如你可能设置了1000个线程,但是某一时刻正好有第1001个线程需要等待所有线程结束才能执行,这种情况如果你限制了线程池线程的个数,就会出现死锁。从开发的另一个角度说,你也不应该限制一个进程使用多少资源,比如一个进程可以使用多少内存,使用多少带宽.因此虽然目前你可以通过GetMaxThreads, SetMaxThreads,GetMinThreads,SetMinThreads ,GetAvailableThreads来进行线程个数的限制,但是他仍然不建议大家这样做。这些限制可能会让你的程序运行的更慢。
以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !