Предотвратить 2 чтения / записи в один и тот же файл одновременно? - PullRequest
0 голосов
/ 15 января 2019

У меня есть несколько модулей, которые должны прочитать число из одного и того же файла queueFile.txt. Каждый раз, когда модуль читает число в файле, ему нужно добавить 1 к числу, а затем записать новый номер обратно в файл. Модули работают очень быстро (иногда для выполнения задач требуется всего несколько миллисекунд)

Я хочу, чтобы только один модуль мог одновременно читать и записывать в queueFile.txt. Если модуль выполняет чтение / запись в файл queueFile.txt, я хочу, чтобы другие модули подождали, пока он не закончил, а затем их очередь.

Я пробовал два способа для этого до сих пор. Оба включают создание файла блокировки, пока используется queueFile.txt.

Метод 1: при этом выдают ошибки, чтобы определить, был ли файл блокировки очереди уже открыт для записи. Если этого не произошло, модуль сам откроет файл блокировки очереди и затем перейдет к работе с основным файлом очереди, а затем закроет файл блокировки очереди, как только это будет сделано. Если он был открыт, модули будут 10000 раз пытаться открыть файл блокировки очереди, а затем выдают сообщение, если оно все еще не удалось.

например:.

var count = 0;
var maxTries = 10000;
while(true) {
try {

    var queueLock = fso.OpenTextFile("queueFileLock.txt", 2, true);
   break;

} catch (err) {

    if (++count == maxTries){

       alert("Could not unlock queue file!");
    }
}
}

// do operation on queueFile.txt


//then close the lock
queueLock.close();

// then next module does its work

Метод 2: Это включает проверку, чтобы увидеть, существует ли файл блокировки очереди. Если это не так, то модуль создает файл блокировки очереди и переходит к работе с основным файлом очереди. Если файл блокировки очереди существует, то модуль будет ожидать, пока активный модуль удалит файл блокировки очереди в конце своей работы.

например:

if((fso.FileExists("queueFileLock.txt"))==false){


var tempWrite = fso.OpenTextFile("queueFileLock.txt", 2, true);
    tempWrite.Close(); 


  }else{

while(fso.FileExists("queueFileLock.txt")){
      sleep(((1000*Math.random())+1000));

      }

  }

// do operation on queueFile.txt

//then close the lock
fso.DeleteFile("queueFileLock.txt") 

// then next module does its work

Используя только один или 2 модуля, описанные выше методы работают нормально. Тем не менее, я хочу, чтобы он был безупречен при использовании 20 модулей или около того. Вышеуказанные методы иногда позволяют 2 или более модулям одновременно получать доступ к основному файлу очереди, что все портит. Я не уверен, как это происходит, потому что только один модуль должен иметь возможность открывать текстовый файл для записи в время, но, похоже, это не тот случай, когда работает много модулей. Может быть, это ошибка с файловой системой Windows, но я не уверен. Я даже попробовал два вышеупомянутых метода вместе, но все же 2 или модули иногда могут одновременно обращаться к queueFile.txt.

Любые идеи о том, как полностью запретить двум модулям доступ к queuefile.txt одновременно?

1 Ответ

0 голосов
/ 15 января 2019

Я использовал этот модуль async-lock для блокировки потоков при обновлении одного и того же объекта в базе данных. Я думаю, что это может иметь отношение и к вашему делу.

...