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

Вниз

Потоки   Найти похожие ветки 

 
Бегун   (2004-04-26 18:45) [0]

Народ, есть несколько потоков, которые ломятся к одному файлу.
Как проще всего организовать доступ.
Необходимо запретить одновременную работу с файлом нескольких потоков.

Надо что-бы когда один поток работает с файлом, остальные - ждали.

Пример: Есть три потока А, В, С.
Если поток А работает с файлом, потоки В, С - ждет.

Поток А отработал.

Поток В работает с файлом, потоки С - ждет.

И т.д.

Пробовал так:
-----------------------------------------
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;
-----------------------------------------

Почему то нестабильно работает. :(

Что здесь не так или
какие еще могут быть решения?


 
Петров Денис ©   (2004-04-26 18:58) [1]

Извращенец....

Глобальная переменная:
var cs: RTL_CRITICAL_SECTION;
Перед запуском первого потока:
InitializeCriticalSection(cs);
После останова последнего потока:
DeleteCriticalSection(cs);
В теле Execute потока:
try
 EnterCriticalSection(cs);
 // что-нибудь делаем с файлом
finally
 LeaveCriticalSection(cs);
end;


 
Бегун   (2004-04-27 12:56) [2]

Если поток А вошел в критическую секцию и работает с файлом, а в это время поток В решил работать с файлом - что будет делать поток В?

Ждать пока завершит работу поток А?


 
Петров Денис ©   (2004-04-27 12:57) [3]

Конечно. EnterCriticalSection для этого и создана.


 
Polevi ©   (2004-04-27 13:09) [4]

>Бегун   (27.04.04 12:56) [2]
>Ждать пока завершит работу поток А?
ждать пока поток A покинет критическую секцию


 
Ozone ©   (2004-04-27 13:24) [5]

В Delphi есть, кстати, уже обьявленный тип КС - TCriticalSection


 
Ozone ©   (2004-04-27 13:37) [6]

TO Петров Денис © [1]

Да, если на то пошло, то нужно писать так


EnterCriticalSection(cs);
try
// что-нибудь делаем с файлом
finally
LeaveCriticalSection(cs);
end;


 
Петров Денис ©   (2004-04-27 13:37) [7]

to Ozone.
Согласен. Опечатка.


 
Петров Денис ©   (2004-04-27 13:43) [8]

Кстати, про TCriticalSection... Ну, давайте тогда уже напишем обертку для типа Integer... со всяким там Create, Free. А то как-то сложно все это :)

Кстати, а что-то я в TCriticalSection не нашел обертки для функции TryEnterCriticalSection... непорядок.


 
Polevi ©   (2004-04-27 14:33) [9]

>Петров Денис ©   (27.04.04 13:43) [8]
[New - Windows NT]


 
Imageman   (2004-04-28 11:13) [10]

если я правильно понял, то критическая секция в потоке A остановит потоки B,C на все время работы с файлом. И это независимо от того, будут потоки C,B пытаться писать в файл или нет! Я к чему клоню - файловые операции довольно длительные и все это время другие потоки будут стоять?

Я бы делал так:

while FileBusy do sleep(0);
EnterCriticalSection(cs);
FileBusy :=true;
LeaveCriticalSection(cs);
try
// что-нибудь делаем с файлом
finally
FileBusy :=false;
end;


но, вообще-то, с критическими секциями, как я чую, не самый лучший вариант. :-)


 
evvcom ©   (2004-04-28 11:31) [11]

А я бы так не делал.


 
panov ©   (2004-04-28 11:38) [12]

>Imageman   (28.04.04 11:13) [10]
Неправильно понял.

Потоки B и С остановятся только при попытке выполнить код, заключенный между Enter... и LeaveCriticalSection

Если в этих потоках можно отложить попытку работы с файлом на некоторое время, используй не EnterCriticalSection, а TryCriticalSection.

Использование критических секций - оптимальный вариант для этой задачи.


 
Игорь Шевченко ©   (2004-04-28 11:53) [13]

TMultiReadExclusiveWriteSynchronyzer не поможет ? Из sysutils.pas


 
VMcL ©   (2004-04-28 12:11) [14]

>>Игорь Шевченко ©  (28.04.04 11:53) [13]

TMultiReadExclusiveWriteSynchronizer


 
Бегун   (2004-04-28 12:42) [15]

Вот так работает:
Ozone ©   (27.04.04 13:37) [6]

Я счаслив!
Все спасибо!


 
Игорь Шевченко ©   (2004-04-28 14:42) [16]

VMcL ©   (28.04.04 12:11)

С меня два чатла :) Я это слово никогда с первого раза написать не мог :)


 
VMcL ©   (2004-04-28 14:56) [17]

>>Игорь Шевченко ©  (28.04.04 14:42) [16]

<offtopic>
 wif "чатл"?
</offtopic>


 
Игорь Шевченко ©   (2004-04-28 16:55) [18]

VMcL ©   (28.04.04 14:56)

#ifdef offtopic
#include <std_offtopic_disclaimer.h>

Чатл - денежная единица на планете Плюк.
(с) Кин-Дза-Дза

#endif


 
VMcL ©   (2004-04-28 18:22) [19]

>>Игорь Шевченко ©  (28.04.04 16:55) [18]

<offtopic>
  Точно. Я уже вспомнил. Thx.
</offtopic>



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

Текущий архив: 2004.05.30;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.042 c
7-1082463805
YuRock
2004-04-20 16:23
2004.05.30
Доступ к COM порту по сети


3-1084335200
Selax__
2004-05-12 08:13
2004.05.30
Не может найти gtintf.dll


3-1083913177
Violina
2004-05-07 10:59
2004.05.30
BDE 5: параметр BLOB SIZE, dead BLOBs <> live BLOBs


14-1084269557
Alex_x
2004-05-11 13:59
2004.05.30
ASProtect, ICE license


3-1084342392
TATIANA
2004-05-12 10:13
2004.05.30
DBImage - ошибка





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский