• 并发MD5计算方法


    MD5与SHA算法一样,利用他们可以计算某段数据的唯一hash值,常用做校验码。而MD5比SHA算法性能高。在我参加的一个项目中,主要用MD5码值来去重,因此对计算性能要求较高。网上有对MD5算法并行化方法,能保证计算结果与线性计算法一样。由于我只需要唯一标记,并不要求它与线性MD5计算结果一样,所以,我通过分片多线程计算的方法实现提速,也充分利用了多核CPU的并行计算优势。

    依据:

    B  = (b1,b2,b3,b4...bn)--->(m1,m2,m3...mn)----+--->M---->(md5) result = 16 bytes

    C#代码:

    class SafeQueue<T>
    {
       // A queue that is protected by Monitor. 
       private Queue<T> m_inputQueue = new Queue<T>();
    
       // Lock the queue and add an element. 
       public void Enqueue(T qValue)
       {
          // Request the lock, and block until it is obtained.
          Monitor.Enter(m_inputQueue);
          try
          {
             // When the lock is obtained, add an element.
             m_inputQueue.Enqueue(qValue);
          }
          finally
          {
             // Ensure that the lock is released.
             Monitor.Exit(m_inputQueue);
          }
       }
    
       // Try to add an element to the queue: Add the element to the queue  
       // only if the lock is immediately available. 
       public bool TryEnqueue(T qValue)
       {
          // Request the lock. 
          if (Monitor.TryEnter(m_inputQueue))
          {
             try
             {
                m_inputQueue.Enqueue(qValue);
             }
             finally
             {
                // Ensure that the lock is released.
                Monitor.Exit(m_inputQueue);
             }
             return true;
          }
          else
          {
             return false;
          }
       }
    
       // Try to add an element to the queue: Add the element to the queue  
       // only if the lock becomes available during the specified time 
       // interval. 
       public bool TryEnqueue(T qValue, int waitTime)
       {
          // Request the lock. 
          if (Monitor.TryEnter(m_inputQueue, waitTime))
          {
             try
             {
                m_inputQueue.Enqueue(qValue);
             }
             finally
             {
                // Ensure that the lock is released.
                Monitor.Exit(m_inputQueue);
             }
             return true;
          }
          else
          {
             return false;
          }
       }
    
       // Lock the queue and dequeue an element. 
       public T Dequeue()
       {
          T retval;
    
          // Request the lock, and block until it is obtained.
          Monitor.Enter(m_inputQueue);
          try
          {
             // When the lock is obtained, dequeue an element.
             retval = m_inputQueue.Dequeue();
          }
          finally
          {
             // Ensure that the lock is released.
             Monitor.Exit(m_inputQueue);
          }
    
          return retval;
       }
    
       // Delete all elements that equal the given object. 
       public int Remove(T qValue)
       {
          int removedCt = 0;
    
          // Wait until the lock is available and lock the queue.
          Monitor.Enter(m_inputQueue);
          try
          {
             int counter = m_inputQueue.Count;
             while (counter > 0)
                // Check each element.
             {
                T elem = m_inputQueue.Dequeue();
                if (!elem.Equals(qValue))
                {
                   m_inputQueue.Enqueue(elem);
                }
                else
                {
                   // Keep a count of items removed.
                   removedCt += 1;
                }
                counter = counter - 1;
             }
          }
          finally
          {
             // Ensure that the lock is released.
             Monitor.Exit(m_inputQueue);
          }
    
          return removedCt;
       }
    
       // Print all queue elements. 
       public string PrintAllElements()
       {
          StringBuilder output = new StringBuilder();
    
          // Lock the queue.
          Monitor.Enter(m_inputQueue);
          try
          {
             foreach( T elem in m_inputQueue )
             {
                // Print the next element.
                output.AppendLine(elem.ToString());
             }
          }
          finally
          {
             // Ensure that the lock is released.
             Monitor.Exit(m_inputQueue);
          }
    
          return output.ToString();
       }
    }
    
    
    //任务节点
    public class TaskItem
    {
       public int idx_;
       public byte[] data_;
       public TaskItem( int idx, byte[] data )
       {
          this.idx_ = idx;
          this.data_ = data;
       }
    }
    //工作线程
    public class WorkThread
    {
        SafeQueue<TaskItem>  packet_;
         AutoResetEvent    notifyEvt_;
         ManualResetEvent     finishEvt_;
         Thread            thread_;
          HashTable         result_;
          
         public WorkThread()
         {
            ....
            thread_ = new Thread( new ThreadStart( this.DoWork ) );
         }
         public void Start()
         {
              thread_.Start();
         }
         //主线程调用:异步添加任务节点
         public void AddDataPacket( TaskItem data )
         {
             packet_.Enqueue( data );
             notifyEvt_.Set();
             
         }
         //主线程调用:等待收集计算结果
         public Hashtable Finish()
         {
                Hashtable rs = new Hashtable( result_ );
               finishEvt_.WaitOne();
               finishEvt_.Reset();
               result_.clear();
               return rs;
         }
         //线程执行函数
         public void DoWork()
         {
               TaskItem  var;
               while(true)
               {
                   notifyEvt_.WaitOne();
                   while(true)
                   {
                       if( packet_.Count > 0 )
                       {
                            //这里取出值错误
                            var = packet_.Dequeue();
                       }
                       if( var == null )
                           break;
                        //task finish
                       if( var.Idx == -1 )
                       {
                           ....
                           this.finishEvt_.Set();
                       }
                   }
               }
         }
    }
    
    public class Md5Hasher
    {
       public void main()
       {
             WorkThread[] test=new WorkThread[5];
    
             for( int i=0; i<100; ++i )
             {
                    //这里输入数据
                   test[i%5].AddDataPacket( ... );
             }
       }
    }
  • 相关阅读:
    Leetcode Binary Tree Paths
    Leetcode Lowest Common Ancestor of a Binary Tree
    Leetcode Lowest Common Ancestor of a Binary Search Tree
    Leetcode Path Sum
    Leetcode Symmetric Tree
    Leetcode Invert Binary Tree
    Leetcode Same Tree
    Leetcode Maximum Depth of Binary Tree
    Python Json&Pickle&模块
    Python Shelve模块
  • 原文地址:https://www.cnblogs.com/feika/p/3514640.html
Copyright © 2020-2023  润新知