![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Потоки [D6, Win2k]
Бегун © (2004-04-26 18:45:00)Народ, есть несколько потоков, которые ломятся к одному файлу.
Как проще всего организовать доступ.
Необходимо запретить одновременную работу с файлом нескольких потоков.
Надо что-бы когда один поток работает с файлом, остальные - ждали.
Пример: Есть три потока А, В, С.
Если поток А работает с файлом, потоки В, С - ждет.
Поток А отработал.
Поток В работает с файлом, потоки С - ждет.
И т.д.
Пробовал так:
-----------------------------------------
function TMyThread.FileBusy: Boolean;
begin
Result:=False;
hMutex:=CreateMutex(nil,False,PChar('FileFree'));
if GetLastError = ERROR_ALREADY_EXISTS then
Result:=True;
end;
procedure TMyThread.Main;
begin
while FileBusy do;
DoSomethingWithFile;
CloseHandle(hMutex);
end;
-----------------------------------------
Почему то нестабильно работает. :(
Что здесь не так или
какие еще могут быть решения?
VMcL (2004-04-28 18:22:00) [1]>>Игорь Шевченко © (28.04.04 16:55) [18]
<offtopic>
Точно. Я уже вспомнил. Thx.
</offtopic>
Игорь Шевченко (2004-04-28 16:55:00) [2]VMcL © (28.04.04 14:56)
#ifdef offtopic
#include <std_offtopic_disclaimer.h>
Чатл - денежная единица на планете Плюк.
(с) Кин-Дза-Дза
#endif
VMcL (2004-04-28 14:56:00) [3]>>Игорь Шевченко © (28.04.04 14:42) [16]
<offtopic>
wif "чатл"?
</offtopic>
Игорь Шевченко (2004-04-28 14:42:00) [4]VMcL © (28.04.04 12:11)
С меня два чатла :) Я это слово никогда с первого раза написать не мог :)
Бегун (2004-04-28 12:42:00) [5]Вот так работает:
Ozone © (27.04.04 13:37) [6]
Я счаслив!
Все спасибо!
VMcL (2004-04-28 12:11:00) [6]>>Игорь Шевченко © (28.04.04 11:53) [13]
TMultiReadExclusiveWriteSynchronizer
Игорь Шевченко (2004-04-28 11:53:00) [7]TMultiReadExclusiveWriteSynchronyzer не поможет ? Из sysutils.pas
panov (2004-04-28 11:38:00) [8]>Imageman (28.04.04 11:13) [10]
Неправильно понял.
Потоки B и С остановятся только при попытке выполнить код, заключенный между Enter... и LeaveCriticalSection
Если в этих потоках можно отложить попытку работы с файлом на некоторое время, используй не EnterCriticalSection, а TryCriticalSection.
Использование критических секций - оптимальный вариант для этой задачи.
evvcom (2004-04-28 11:31:00) [9]А я бы так не делал.
Imageman (2004-04-28 11:13:00) [10]если я правильно понял, то критическая секция в потоке A остановитпотоки B,C на все время работы с файлом. И это независимо от того, будут потоки C,B пытаться писать в файл или нет! Я к чему клоню - файловые операции довольно длительные и все это время другие потоки будут стоять?
Я бы делал так:
while FileBusy do sleep(0);
EnterCriticalSection(cs);
FileBusy :=true;
LeaveCriticalSection(cs);
try
// что-нибудь делаем с файлом
finally
FileBusy :=false;
end;
но, вообще-то, с критическими секциями, как я чую, не самый лучший вариант. :-)
Polevi (2004-04-27 14:33:00) [11]>Петров Денис © (27.04.04 13:43) [8]
[New - Windows NT]
Петров Денис (2004-04-27 13:43:00) [12]Кстати, про TCriticalSection... Ну, давайте тогда уже напишем обертку для типа Integer... со всяким там Create, Free. А то как-то сложно все это :)
Кстати, а что-то я в TCriticalSection не нашел обертки для функции TryEnterCriticalSection... непорядок.
Петров Денис (2004-04-27 13:37:00) [13]to Ozone.
Согласен. Опечатка.
Ozone (2004-04-27 13:37:00) [14]TO Петров Денис © [1]
Да, если на то пошло, то нужно писать так
EnterCriticalSection(cs);
try
// что-нибудь делаем с файлом
finally
LeaveCriticalSection(cs);
end;
Ozone (2004-04-27 13:24:00) [15]В Delphi есть, кстати, уже обьявленный тип КС - TCriticalSection
Polevi (2004-04-27 13:09:00) [16]>Бегун (27.04.04 12:56) [2]
>Ждать пока завершит работу поток А?
ждать пока поток A покинет критическую секцию
Петров Денис (2004-04-27 12:57:00) [17]Конечно. EnterCriticalSection для этого и создана.
Бегун (2004-04-27 12:56:00) [18]Если поток А вошел в критическую секцию и работает с файлом, а в это время поток В решил работать с файлом - что будет делать поток В?
Ждать пока завершит работу поток А?
Петров Денис (2004-04-26 18:58:00) [19]Извращенец....
Глобальная переменная:
var cs: RTL_CRITICAL_SECTION;
Перед запуском первого потока:
InitializeCriticalSection(cs);
После останова последнего потока:
DeleteCriticalSection(cs);
В теле Execute потока:
try
EnterCriticalSection(cs);
// что-нибудь делаем с файлом
finally
LeaveCriticalSection(cs);
end;