[英]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.