Предположим, мне нужно прочитать / записать 1000 файлов из нескольких потоков (т.е. один файл может быть записан из нескольких потоков). Я не хочу использовать одну блокировку для защиты всех файлов, так как это будет медленно. Все, что я могу придумать, - это иметь List<object>, чтобы удерживать 1000 блокировок и делать что-то вроде lock(list[i]) { write to i'th file}. Это правильный способ сделать это?

Это будет подход:

    static object _list_lock = new object();
    static List<object> locks = new List<object>();

    public static void Main(string[] args)
    {
        for(int i=0; i<1000; i++)
            locks.Add(new object());

        var tasks = new List<Task>();
        for(int i=0; i<15000; i++)
        {
            var t = Task.Run(() =>
                             {
                                 int file = (new Random()).Next(0, 1000);
                                 object l;
                                 lock(_list_lock)
                                 {
                                     l = locks[file];
                                 }
                                 lock(l)
                                 {                                         
                                     //write to file 'file' 
                                 }
                             });
            tasks.Add(t);
        }
        tasks.ForEach(f => f.Wait());
    }
0
ren 3 Апр 2014 в 18:21
2
Возможно, вам не нужны 1000, поскольку вы можете достичь других ограничений (дескрипторы файлов, физический ввод-вывод, память и т. Д.), Но вы можете попробовать запустить несколько из них параллельно. Конечно, вам также нужна блокировка для управления вашим списком блокировок :-) .Net Framework уже включает конструкцию, которая может помочь с типом активности, на которую вы смотрите, - ReaderWriterLock; msdn.microsoft.com/en-us/library/… < / а>
 – 
dash
3 Апр 2014 в 18:31

1 ответ

Лучший ответ

Если у вас есть List <> путей к файлам, который проверяется перед чтением или записью, я бы подумал, что он должен быть равен количеству запущенных потоков.

Вам просто нужно убедиться, что класс, который добавляет и удаляет записи из списка, является многопоточным, чтобы два потока не могли добавить один и тот же путь одновременно.

2
WhoIsRich 3 Апр 2014 в 18:50