![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как правильно организовать поток? [D6, Win2k, WinXP]
tim © (2003-10-07 10:58:00)
Добрый день, уважаемые. Мне небходимо в одном потоке заполнять массив данными и, соответственно, если они там есть, то активируется второй поток, который эти данные обрабатывает и после обработки из массива удаляет и приостанавливается. И так далее.
Подскажите как наиболее грамотно организовать логику?
tim (2003-10-07 12:18:00) [1]
спасибо, попробую разобраться, хотя вроде свой вариант с бесконечном цикле во втором потоке, который время от времени засыпает и будится при добавлении данных в первом потоке, тоже заработал.
хотя, конечно, вариант с критическими секциями будет пограмотней.
кстати интересная особенность, не относящаяся к делу:
для экспериментов создал две пустые и абсолютно одинаковые базы в MS Sql 2000. забэкапил своей программой. Результат:
a1.bak 3.31 mb
a2.bak 2.48 mb
у кого есть комментарии?
Polevi (2003-10-07 12:05:00) [2]
упс, ReleaseSemaphore в GetData не нужен, конечно же
Polevi (2003-10-07 12:04:00) [3]
создаешь очередь и семафор (CreateSemaphore)
procedure AddData(SomeData);
begin
EnterCriticalSection
try
DataList.Add(SomeData)
ReleaseSemaphore
finally
LeaveCriticalSection
end;
end;
основной поток вызвает AddData
второй поток WaitForSingleObject"ом ждет семафор
как только семафор сигналит - очередь данных не пуста - поток просыпается и выбирает данные из очереди
procedure GetData:TSomeData
begin
EnterCriticalSection
try
Result:=DataList[0];
DataList.Delete(0);
ReleaseSemaphore
finally
LeaveCriticalSection
end;
end;
tim (2003-10-07 11:44:00) [4]
"manual reset" event - это флаг, как я понимаю?
или не понимаю?
проблема в том, что первый поток через определенный промежуток времени обегает массив и если элемент массива (поле Время)
равен текущему, то этот элемент попадает в очередь. А второй поток, основываясь на данных из очереди делает бэкап (SQL Server но это не принципиально). Соответственно, я не могу приостановить добавление данных из первого потока, так как определенное задание может проспать!
Хотя, очередь - это всего лишь набор указателей и весьма несущественно, если она в это время пополнится, я могу считать себя правым?
N169 (2003-10-07 11:35:00) [5]
Можно посадить "manual reset" event, изначально сброшенный.
Первый поток заливает данные и устанавливает event, начинает работу 2-й поток (который должен ожидать установки event, чтобы продолжить работу).
После того как 2-й поток отработает и удалит данные, он (П#2) сбрасывает event и делает на него синхронизацию с помощью WaitForSingleObject().
Далее циклы могут повторяться.
+ П#1 не должен манипулировать общими данными П#1 и П#2, пока event установлен.