Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];

Вниз

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

 
domosed ©   (2005-08-22 01:19) [0]

Вот такая задача:
два приложения периодически обращаются к одному и томуже файлу (читают записывают читают записывают читают записывают) вот... есть вероятность что в то время как один попытается записать, другой попытается прочитать что нежелательно. Вот этот вариант правильный или нет:

AssignFile(t,"xxx.xxx");
rewrite(t);
repeat
write(t,x);
until IOResult=0;
CloseFile(t);
{а в это время приложение номер 2 пытается сделать следующее}
AssignFile(t,"xxx.xxx");
reset(t);
repeat
read(t,x);
until IOResult=0;
CloseFile(t);


 
Defunct ©   (2005-08-22 02:02) [1]

> вариант правильный или нет

нет


 
tesseract ©   (2005-08-22 09:58) [2]

CreteFile по умолчанию открывает файл как раз в эксклюзивном режиме(если не задавать свойства File_Share_read, File_Share_Write)


 
Alexander Panov ©   (2005-08-22 11:32) [3]

domosed ©   (22.08.05 1:19)

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


 
domosed ©   (2005-08-22 17:18) [4]

Нужно чтобы пока одно приложение работает с файлом другое просто ждало своей очереди (пока первый его освободит)
Файлы содержат по одной переменной integer
Пока придумал такой ещё вариант


{запись}
procedure writef(var filename:string; dat:integer);
var HFile,HMap:THandle;
   Adrbase:^integer;
begin
repeat
HFile:=FileOpen(filename,fmOpenReadWrite or fmShareExclusive);
until HFile<>0;
repeat
Hmap:=CreateFileMapping(HFile,nil,PAGE_READWRITE,0,0,nil);
until Hmap<>0;
repeat
Adrbase:=MapViewOfFile(HMap,FILE_MAP_WRITE,0,0,0);
until not(Adrbase=nil);
AdrBase^:=dat;
UnmapViewOfFile(AdrBase);
CloseHandle(HMap);
CloseHandle(HFile);
end;
{чтение}
procedure readf(var filename:string;out dat:integer);
var HFile,HMap:THandle;
   Adrbase:^integer;
begin
repeat
HFile:=FileOpen(filename,fmOpenReadWrite or fmShareExclusive);
until HFile<>0;
repeat
Hmap:=CreateFileMapping(HFile,nil,PAGE_READWRITE,0,0,nil);
until Hmap<>0;
repeat
Adrbase:=MapViewOfFile(HMap,FILE_MAP_WRITE,0,0,0);
until not(Adrbase=nil);
dat:=AdrBase^;
UnmapViewOfFile(AdrBase);
CloseHandle(HMap);
CloseHandle(HFile);
end;


катит не катит такой вариант


 
domosed ©   (2005-08-22 17:23) [5]

Да, и вот ещё вопрос появился
Могут ли два приложения просто читать файл одновременно используя простой read(t,x); еще при этом и передвигать указатель Seek(t,123);


 
Defunct ©   (2005-08-22 18:45) [6]

domosed ©   (22.08.05 17:18) [4]
> катит не катит такой вариант

второе.


domosed ©   (22.08.05 17:23) [5]

> Могут ли два приложения просто читать файл одновременно используя простой read(t,x); еще при этом и передвигать указатель Seek(t,123);

Могут. при FileMode = 1
но лучше воспользоваться:

TFileStream.Create( fFileName, fmOpenRead or fmShareDenyNone );
либо
TFileStream.Create( fFileName, fmReadWrite or fmShareDenyNone );

PS: по существу, вопрос синхронизации доступа к одному файлу уже решен множествами СУБД. Используй любую стандартную базу, обеими приложениями.


 
TUser ©   (2005-08-22 19:08) [7]

Мьютексы, например.


 
domosed ©   (2005-08-22 21:05) [8]

Про базы данных я абсолютно ничего не знаю:(
Нда примерчик мой действительно не катит. Почемуто виснет на

Hmap:=CreateFileMapping(HFile,nil,PAGE_READWRITE,0,0,nil);

А как тогда без баз данных решить?


 
Defunct ©   (2005-08-22 21:27) [9]

domosed ©   (22.08.05 21:05) [8]

Чес слово, базы не настолько сложны, чтобы их шарахаться. Впору начинать читать статьи по работе с базами данных. Рекомендую Interbase, для не на мой взгляд в делфи самая удобная обвязка.

> А как тогда без баз данных решить?
> два приложения периодически обращаются к одному и томуже файлу (читают записывают читают записывают читают записывают)


Пример:

const
 ASharedFile = "1.txt";

{$R *.dfm}
procedure ExclusiveWrite( var Buf; count: integer);
var
 Stream : TFileStream;
 Captured : boolean;
begin
  Captured := false;

  if not FileExists( ASharedFile ) then
     TFileStream.Create( ASharedFile, fmCreate).Free;

// ждем разрешения доступа
  while not Captured do
  try
     Stream := TFileStream.Create( ASharedFile, fmOpenWrite or fmShareDenyWrite);
     Captured := True;
  except
     Captured := false;
     sleep(10);
  end;

// записываем
  Stream.Position := Stream.Size;
  Stream.Write( Buf, Count );
  Stream.Free;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
 S : String;
begin
 S := "date = " + FormatDateTime("dd-mm-yyyy  hh:nn:ss", Now ) +
      "(process id = " + IntToHex( GetCurrentProcessId, 8 ) + ")" +
      #13+#10;
 ExclusiveWrite( S[1], Length(S) );
end;


Разултат выполнения трех одновременно запущенных программ:

date = 22-08-2005  20:26:34(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 00000FA8)


C чтением быть по аналогии.


 
Defunct ©   (2005-08-22 21:27) [10]

domosed ©   (22.08.05 21:05) [8]

Чес слово, базы не настолько сложны, чтобы их шарахаться. Впору начинать читать статьи по работе с базами данных. Рекомендую Interbase, для не на мой взгляд в делфи самая удобная обвязка.

> А как тогда без баз данных решить?
> два приложения периодически обращаются к одному и томуже файлу (читают записывают читают записывают читают записывают)


Пример:

const
 ASharedFile = "1.txt";

{$R *.dfm}
procedure ExclusiveWrite( var Buf; count: integer);
var
 Stream : TFileStream;
 Captured : boolean;
begin
  Captured := false;

  if not FileExists( ASharedFile ) then
     TFileStream.Create( ASharedFile, fmCreate).Free;

// ждем разрешения доступа
  while not Captured do
  try
     Stream := TFileStream.Create( ASharedFile, fmOpenWrite or fmShareDenyWrite);
     Captured := True;
  except
     Captured := false;
     sleep(10);
  end;

// записываем
  Stream.Position := Stream.Size;
  Stream.Write( Buf, Count );
  Stream.Free;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
 S : String;
begin
 S := "date = " + FormatDateTime("dd-mm-yyyy  hh:nn:ss", Now ) +
      "(process id = " + IntToHex( GetCurrentProcessId, 8 ) + ")" +
      #13+#10;
 ExclusiveWrite( S[1], Length(S) );
end;


Разултат выполнения трех одновременно запущенных программ:

date = 22-08-2005  20:26:34(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000FA8)
date = 22-08-2005  20:26:35(process id = 0000095C)
date = 22-08-2005  20:26:35(process id = 00000A0C)
date = 22-08-2005  20:26:35(process id = 00000FA8)


C чтением быть по аналогии.


 
Defunct ©   (2005-08-22 21:31) [11]

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


 
domosed ©   (2005-08-23 00:28) [12]

Примного благодарен!



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.011 c
14-1124344994
TButton
2005-08-18 10:03
2005.09.11
теодолитный ход...


14-1124072493
Думкин
2005-08-15 06:21
2005.09.11
15 августа! С днем ребята


3-1122560693
PAI
2005-07-28 18:24
2005.09.11
Как русифицировать Database?


3-1122867252
rentgen
2005-08-01 07:34
2005.09.11
Как переместить запись?


1-1124348932
Juice
2005-08-18 11:08
2005.09.11
Сохранение published-свойств





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский