• 从线程池看《操作系统》专业课的作用【转自杨中科学生大本营】


    .Net内置的ThreadPool类大大方便了多线程程序的开发,.Net程序员不用像Java程序员那样自己去写线程池或者找别人写好的线程池了。
    不过ThreadPool也有用起来不方便的地方,因为ThreadPool是一个进程内的单一线程池,无法构建单一的线程池,由于所在的线程中可能有其他地方向ThreadPool中添加任务,因此ThreadPool没有提供一个“放进去的所有任务执行完毕”这样的功能。难道我们就没有办法了吗?

    不用担心,其实非常简单,只要借助于计算机专业都要学习的一门主干课《操作系统》中PV操作、信号量的知识点,可以很轻松的解决。为每个放到ThreadPool中的任务关联一个信号量,每个任务执行完毕后执行信号量的Set操作,Queue任务的主线程维护一个每个任务管理信号量的列表,把所有任务都Queue到ThreadPool中以后,逐个调用信号量的Wait操作,这样如果这个信号量对应的任务还没有执行完毕,那么Wait操作就会等待,如果执行完毕则Wait操作就不会阻塞,这样当所有的信号量Wait都返回了,就说明放进去的所有任务就都执行完成了。
    我封装了一个简单的ThreadPoolEx类如下:

    public class ThreadPoolEx  
    {  
        
    private class WorkItemInfo  
        {  
            
    public AutoResetEvent AutoResetEvent { getset; }  
            
    public WaitCallback WaitCallback { getset; }  
            
    public object UserState { getset; }  
        }  
        
    private List<AutoResetEvent> handlerStack = new List<AutoResetEvent>();  
        
    public void QueueWorkItem(WaitCallback callBack,object userstate)  
        {  
            WorkItemInfo info 
    = new WorkItemInfo();  
            info.AutoResetEvent 
    = new AutoResetEvent(false);  
            handlerStack.Add(info.AutoResetEvent);  
            info.WaitCallback 
    = callBack;  
            info.UserState 
    = userstate;  
               
            ThreadPool.QueueUserWorkItem((state) 
    => {  
                WorkItemInfo workItemInfo 
    = (WorkItemInfo)state;  
                
    try 
                {  
                    workItemInfo.WaitCallback(workItemInfo.UserState);  
                }  
                
    finally 
                {  
                    workItemInfo.AutoResetEvent.Set();  
                }  
            }, info);  
        }  
        
    public void WaitAllComplete()  
        {  
            
    foreach(AutoResetEvent handler in handlerStack)  
            {  
                handler.WaitOne();  
            }  
        }  
    }

    所有任务Queue进去以后,调用WaitAllComplete方法,当WaitAllComplete方法返回以后就说明任务执行完毕了。
    调用方法实例代码如下:

    ThreadPoolEx tpe = new ThreadPoolEx();
                
    for (int i = 100; i > 0; i--)
                {
                    tpe.QueueWorkItem((state) 
    =>
                    {
                        Console.WriteLine(state);
                    },i);                
                }
                tpe.WaitAllComplete();
    Console.WriteLine(
    '执行完成!');

    《操作系统》是非常有用的,学好计算机专业课发展才能更好。

  • 相关阅读:
    Mysql:Optimization and Indexes:优化-索引
    Mysql:Optimizing for Many Tables:如果你的表太多,怎办?
    Mysql:Internal Temporary Table:【不可直接控制】的【内部】临时表:不要blob、不要text、不要太长>512的(二进制)字符串列!
    Mysql:Optimizing Memory Use、Enabling Large Page Support:内存使用优化:【global + session】
    Mysql:Symbolic Links:软链接(符号链接)
    Mysql:--secure-auth、--secure-file-priv
    Mysql:Security Issues with LOAD DATA LOCAL:【LOCAL】关键字的安全问题:--load-infile
    续:MONyog 8.9.1:IderaSQLDiagnosticManagerForMySQL-Windows-x86 8.9.1:无限期试用:变相破解
    续:SQLyog Trial v13.1.5 x64:无限期试用:变相破解
    SpringBoot文件的上传与下载
  • 原文地址:https://www.cnblogs.com/scy251147/p/1814808.html
Copyright © 2020-2023  润新知