Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.09.11;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.044 c
1-1124783767
user51
2005-08-23 11:56
2005.09.11
как проеобразовать string к pwidechar


14-1124224030
Cheaterr
2005-08-17 00:27
2005.09.11
Вопрос к тем, кто работает на производстве или торговых компаниях


1-1124462191
murz
2005-08-19 18:36
2005.09.11
Сжатие приложений


14-1124245340
Думкин
2005-08-17 06:22
2005.09.11
17 августа. С днем рождения.


2-1123496878
Jann
2005-08-08 14:27
2005.09.11
запрос к базе