您的位置:首页 > 其它

并发MD5计算方法

2014-01-11 00:06 204 查看
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( ... );
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: