簡體   English   中英

多線程讀取隨機文件

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM