Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.15.144.170] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Нужно организовать многопоточный доступ к файлам данных. При этом если один экземпляр записывает файл нужно временно заблокировать доступ к нему из других экземпляров. Делается это обычно так:
1) Создается временный файл, который означает, что редактируемый файл сейчас занят, 2) Производятся действия, 3) Временный файл удаляется. При чтении происходит проверка 1) Если временный файл существует то ждем 2) Ждем до тех пор, пока временный файл перестанет существовать 3) Читаем файл и т.п. Я это когда-то уже пытался делать при помощь sysutils и fileexists(). Но от этого решения пришлось отказаться из-за постоянных Runtime'ов. Теперь задача даже посложнее: нужно проверять на наличие временного файла без sysutils, стандартными средствами system. Какие будут соображения? |
Сообщ.
#2
,
|
|
|
Сообщ.
#3
,
|
|
|
Мне больше понравился вариант Vesper'а:
function FileExists(fname: string): boolean; var fh: text; begin assign(fh, fname); {$i-} reset(fh); close(fh); {$i+} result := ioresult = 0; end; Надо будет попробовать. Но вопрос блокировки файлов интересен сам по себе. Может, у кого-нибудь есть другие гениальные идеи? |
Сообщ.
#4
,
|
|
|
Да. только в этом варианте нужно Close выполнять только в том случае, если файл открылся. Иначе может быть ошибка. Файл не открыт, а мы пытаемся его закрыть.
|
Сообщ.
#5
,
|
|
|
Блокировка файла... хм... А что тут сложного?... ИМХО это элементарно...
открываешь файл для добавления инфы (не для чтения, а добавления!), а открытый таким образом файл ОСь не даст изменить другим прогам, пока ты его не закроешь.... Добавлено Таким образом, если файл открыт для чтения, то другие проги то же могут его открыть, а вот если для записи, то другие проги должны подождать, им ОСь просто не даст открыть файл.... |
Сообщ.
#6
,
|
|
|
Это ты так думаешь. На самом же деле когда два процесса пытаются писать в один файл, оба вылетят с Runtime Error, а файл будет поврежден. Так что не даром люди задумываются над multithreading'ом.
Хм... Тогда делаем так: function FileExists(fname: string): boolean; var fh: text; begin assign(fh, fname); {$i-} reset(fh); if ioresult = 0 then close(fh); {$i+} result := ioresult = 0; end; |
Сообщ.
#7
,
|
|
|
так нельзя. После первого обращения к функции (на самом деле это функция) ioresult она перестанет возвращать ошибку.
Нужно так: function FileExists(fname: string): boolean; var fh: text; begin FileExists:=true; assign(fh, fname); {$i-} reset(fh); {$i+} if ioresult = 0 then close(fh) else FileExists:=false; end; |
Сообщ.
#8
,
|
|
|
Далее следует тестирование, но это завтра. А пока такой вопрос: как лучше оргинизовать ожидание (типа sleep() в WinAPI или delay() в CRT), чтобы меньше загружать систему? Поиск выдал код JinX'а:
Цитата repeat asm mov ax,1680h int 2Fh end until УсловиеВыхода |
Сообщ.
#9
,
|
|
|
Если прога под винду, то Sleep
|
Сообщ.
#10
,
|
|
|
Цитата Some1 @ 24.09.04, 20:12 Если прога под винду, то Sleep Если под виндовс то файл открывается с соответствующей ShareMode и не городится огород |
Сообщ.
#11
,
|
|
|
Цитата Some1, 25.09.04, 00:12 Если прога под винду, то Sleep Можно еще создать пустой процесс и периодически его опрашивать... Смотреть в DRKB про WinExec and Wait, там был опрос процесса при котором прога работала без тормозов, т.е. могла обрабатывать сообщения и т.д... Если ниче не найдете, могу помочь написать готовый исходник.... |
Сообщ.
#12
,
|
|
|
Прога кроссплатформенная. Под Win32, Linux, FreeBSD, NetBSD, OpenBSD, OS/2, QNX и т.д.
Добавлено В FPC проблем с CRT нет, так что решил использовать delay(). |
Сообщ.
#13
,
|
|
|
Цитата ZenIA, 25.09.04, 08:29 Если под виндовс то файл открывается с соответствующей ShareMode и не городится огород Угумс... критические секции и события тоже не отменяли. Trustmaster, случаем не Win32 платформа? |
Сообщ.
#14
,
|
|
|
Я же сказал, что на FPC под все поддерживаемые платформы. Поэтому WinAPI, ясное дело, не подходит.
Временная блокировка, вроде бы, работает. Прога, правда, вылетает с Runtime Error: General Protection fault, но на совсем другом этапе. Предполагаю, что что где-то ошибся с динамическим изменением размера массива. Но это уже совсем другая история. Всем спасибо за сочувствие, тема же остается открытой: другие кроссплатформенные способы общего доступа к файлам. |
Сообщ.
#15
,
|
|
|
Цитата Trustmaster, 24.09.04, 16:29 Нужно организовать многопоточный доступ к файлам данных Эти потоки будут потомками одной проги или разных? |