[英]Multiple threads reading random files
我有一个线程池,所有线程都有一套固定的图像。 假设他们有100张图片。 我需要检测哪个图像包含驻留在图像库中的另一个图像。
线程1-100张图片
线程2-100张图片
线程3-100张图片
线程4-100张图片
图片库-50张图片
现在我需要所有的线程来看看图像底座内部,看看图像中的一个,他们持有类似图像基地之一。 我有我的图像匹配完成后,我所担心的是,如果多个线程可能会打开相同的图像文件。 解决这个问题的正确方法是什么? 最好不要“锁定”每个IO的所有其他线程。
谢谢 !
像这样的事情呢,每个线程都有一个对图像库的引用,并提供一个将为图像库中的每个文件调用的委托? 这是图像库看起来的骨架。
public class ImageBank {
public delegate bool ImageProcessorDelegate(String imageName);
private readonly List<String> _imageBank;
public ImageBank()
{
// initialize _imageBank with list of image file names
}
private int ImageBankCount {
get {
lock(_imageBank) {
return _imageBank.Count;
}
}
}
private List<String> FilterImageBank(ISet<String> exclude)
{
lock(_imageBank)
{
return _imageBank.Where(name => !exclude.Contains(name)).ToList();
}
}
public void ProcessImages(ImageProcessorDelegate imageProcessor)
{
var continueProcessing = true;
var processedImages = new HashSet<String>();
var remainingImages = new List<String>();
do
{
remainingImages = FilterImageBank(processedImages);
while(continueProcessing && remainingImages.Any())
{
var currentImageName = remainingImages[0];
remainingImages.RemoveAt(0);
// protect this image being accessed by multiple threads.
var mutex = new Mutex(false, currentImageName);
if (mutex.WaitOne(0))
{
try
{
// break out of loop of the processor found what it was looking for.
continueProcessing = imageProcessor(currentImageName);
}
catch (Exception)
{
// exception thrown by the imageProcessor... do something about it.
}
finally
{
// add the current name to the set of images we've alread seen and reset the mutex we acquired
processedImages.Add(currentImageName);
mutex.ReleaseMutex();
}
}
}
}
while(continueProcessing);
}
}
然后,每个线程将有其图像的列表( _myImageList
)和ThreadProc
,看起来是这样的:
void ThreadProc(object bank)
{
var imageBank = bank as ImageBank;
foreach(var myImage in _myImageList)
{
imageBank.ProcessImages(imageName =>
{
// do something with imageName and myImage
// return true to continue with the next image from the image bank
// or false to stop processing more images from the image bank
}
);
}
}
假设所有线程都具有必须处理的同一组图像,并假定这些文件的页面位于列表或其他集合中,则可以尝试执行以下操作:
// A shared collection
List<string> paths = new List<string>();
// Fill this collection with your fixed set.
IEnumerator<T> e = paths.GetEnumerator();
// Now create all threads and use e as the parameter. Now all threads have the same enumerator.
// Inside each thread you can do this:
while(true)
{
string path;
lock(e)
{
if (!e.MoveNext())
return; // Exit the thread.
path = e.Current;
}
// From here, open the file, read the image, process it, etc.
}
在此示例中,您仅对枚举器加了锁。 同一时间只能读取一个线程。 因此,每次调用它时,都会引出一条不同的路径。
在锁之外,您可以执行所有处理,I / O等。
当然,集合也可以是另一种类型,例如数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.