并发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( ... );
         }
   }
}

 

posted @ 2014-01-11 00:06  samu  阅读(1600)  评论(0编辑  收藏  举报