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

Вниз

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

 
__Unknown__   (2007-07-11 19:59) [0]

Хотел спросить, корректно ли
использовать такую конфигурацию!

В потоке за место метода Synchronize() использовать
TCriticalSection!

т.е.:

...
CriticalSection.Enter;
OnData(Self);
CriticalSection.Leave;
...

И следующий вопрос:
Если у меня запущен поток и мне надо добавить в него данные, его обязательно приостанавливать или нет?


 
Однокамушкин   (2007-07-11 20:27) [1]

Некорректно...

Synchronize используется для синхронизации с кодом VCL, конкретно - передаёт управление главной нити для того, чтобы она выполнила нужный метод... а критическая секция даёт результат только тогда, когда другая нить тоже использует эту же самую еритическую секцию, чего в коде VCL не наблюдается...

> Если у меня запущен поток и мне надо добавить в него данные,
>  его обязательно приостанавливать или нет?

Нет, если этот поток в момент добавления данных не обращается к ним... Вот тут как раз побойдёт критическая секция, она приостановит ваш поток только в том случае, если он будет выполнять синхронизируемую часть кода, а нет - так пусть его работает...


 
Инс ©   (2007-07-11 20:31) [2]


> Если у меня запущен поток и мне надо добавить в него данные


Этот момент лучше бы пояснить...


 
__Unknown__   (2007-07-11 20:33) [3]

Или если не использовать TThread, а создавать поток через CreateThread можно ли использовать CriticalSection для синхронизации с тем же VCL?


 
Инс ©   (2007-07-11 20:38) [4]

Тут дело не в том, через что создавать поток (к тому же, вместо CreateThread следует использовать BeginThread). Однокамушкин все пояснил. Для того, чтобы синхронизировать с кодом VCL, нужно, чтобы он осуществлял вход в ту же критическую секцию. Ничего подобного в VCL не предусмотрено, это принципиально однопоточная библиотека.

Что Вы хотите сделать?


 
__Unknown__   (2007-07-11 20:45) [5]

>Инс
Смотри, данные приходят и уходят для этого у потока есть два буфера (вход и выход). Т.е. у каждого потока свой буфер с данными, но меня беспокоит такой вопрос. Не произойдет ли ошибка, если во время работы потока я буду добавлять данные в выходной буфер из основной формы, а в это время мой поток их начнет записывать дальше?


 
Инс ©   (2007-07-11 20:51) [6]


> [5] __Unknown__   (11.07.07 20:45)


Вот для этого критические секции и нужны. Сделайте так:
1. Заведите по одной критической секции на каждый дочерний поток, сделайте ее свойством потомка TThread
2. Пусть главный поток при добавлении данных получает ссылку на критическую секцию нужного наследника TThread, осуществляет вход, добавляет данные, осуществляет выход.
3. Пусть дочерний поток, перед обращением к входным данным осуществляет вход в свою критическую секцию, работает с данными, осуществляет выход.

Только старайтесь, чтобы код внутри критической секции выполнялся как можо меньше времени, иначе потоки только и будут, что ждать, пока другой освободит критическую секцию.


 
__Unknown__   (2007-07-11 20:55) [7]

Т.е. у меня идет также вывод данных с каждого потока на экран, и я хотел поставить Критическую секцию за место Synchronize, т.к. Synchronize отсылает сообщение к окну основного потока и иногда она не срабатывает скажем при закрытии приложения!


 
Инс ©   (2007-07-11 20:55) [8]


> Не произойдет ли ошибка, если во время работы потока я буду
> добавлять данные в выходной буфер из основной формы, а в
> это время мой поток их начнет записывать дальше?


Ух ты, еще и вЫходной буфер. Боже. Произойдет конечно, если синхронизировать не будете. Одновременно двое пишут в одну и ту же область, как вы думаете, что в этой области будет записано? Синхронизировать надо. В [6] п.2. слово "входным" читать как "выходным", если конечно вы не опечатались.


 
Инс ©   (2007-07-11 21:00) [9]


> Т.е. у меня идет также вывод данных с каждого потока на
> экран


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

Уважаемый, а не рано ли вы синхронизацией потоков занялись? Может почитать что-нибудь по этой теме сначала?


 
__Unknown__   (2007-07-11 21:02) [10]

T.е. я делаю Terminate и приэтом должен отработать скажем OnTerminate, но иногда до него не доходит! Но мне при этом нужно записать оставшиеся данные... Получается так, что я теряю данные!


 
Инс ©   (2007-07-11 21:06) [11]


> T.е. я делаю Terminate


Какой Terminate? TThread.Terminate, Application.Terminate, TerminateThread, TerminateProcess?


 
__Unknown__   (2007-07-11 21:15) [12]

Thread.Terminate;


 
Инс ©   (2007-07-11 21:19) [13]

А флажок Terminated внутри потока анализируете?

Кстати, после вызова Terminate можно дождаться его завершения. Например, с помощью метода WaitFor


 
__Unknown__   (2007-07-11 21:23) [14]

Внутри как положено!
While Not Terminated do
Begin
...
End;

А после WaitFor все зависает!
Все синхронизации возвращаются нормально, т.к. в них только указания статуса и вывод информации на экран!
Все как должно быть и все равно почему-то не работает :)
Вот поэтому и задал вопрос!


 
Инс ©   (2007-07-11 21:25) [15]


> А после WaitFor все зависает!


Я конечно не телепат, но вы WaitFor точно из главного потока вызываете? Нужно так:
th1.Terminate;
th1.WaitFor;


 
__Unknown__   (2007-07-11 21:31) [16]

Да извини! :)

If Not FClient.Terminated Then
 Begin
    FClient.Terminate;
    FCliet.WaitFor;
 End;
FClient.Free;


 
__Unknown__   (2007-07-11 21:34) [17]

Виснет на WaitFor если убираю, то на Free; ;)


 
Инс ©   (2007-07-11 21:41) [18]


> [16] __Unknown__   (11.07.07 21:31)


В общем-то правильно. Почему же зависает? Взаимная блокировка из-за использования Syncronize маловероятна, так как из WaitFor вызывается CheckSynchronize. Но очевидно, что поток FClient не может завершиться, попробуйте разобраться почему.


 
Сергей М. ©   (2007-07-12 08:12) [19]


> Виснет на WaitFor если убираю, то на Free


Это означает что метод Thread.Execute по каким-то причинам не завершает свое выполнение.
Или в теле поточной функции возникло необработанное исключение.


 
Инс ©   (2007-07-12 10:32) [20]


> Или в теле поточной функции возникло необработанное исключение.


И что? В этом случае поток почти сразу же завершится. И WaitFor вернет управление. Разве нет?


 
__Unknown__   (2007-07-15 12:03) [21]

Я разобрался! Вопрос снят! :)
Случай такой Class который вызывал MyThreadClass и иногда было так что THREAD завершился а мой Class вызывал  WaitFor на чем и вис!
Т.к. я посмотрел, что в Thread метод WaitFor использует MSGWaitForMultipleEvents(если не ошибаюсь) и на этом виснет!!!!! :)
Баг написан мной!!!! Слишком намудрил с проверками в событиях!
Исправил, все работает :)
Всем спасибо


 
Инс ©   (2007-07-15 13:22) [22]


> Случай такой Class который вызывал MyThreadClass и иногда
> было так что THREAD завершился а мой Class вызывал  WaitFor
> на чем и вис!

Рад, что все заработало, но вот интерпретровали ошибку вы точно не правильно. Если поток уже завершился, то MsgWaitForMultipleObjects вернет управление сразу же, а не зависнет. Так что... что-то вы не так поняли либо нам не договариваете ;-)


 
SLoW.AlfaMoon.Com   (2007-07-17 10:34) [23]

2 Инс

С исключениями в потоках да и в dll вообще ситуация темная. ПРи выбросе исключения в потоке поток просто замерзает и все, если нет обработчиков исключений. Т.е. обнаружить оное практически очень сложно.


 
DVM ©   (2007-07-17 14:08) [24]


> Т.е. обнаружить оное практически очень сложно.

Совсем не сложно, если об этом позаботиться заранее


 
Anatoly Podgoretsky ©   (2007-07-17 14:34) [25]

> SLoW.AlfaMoon.Com  (17.07.2007 10:34:23)  [23]

А почему нет, может стоит озаботиться?


 
SLoW.AlfaMoon.Com   (2007-07-17 17:48) [26]

Неаккуратно написал... последнее предложение читать так: Т.е. обнаружить оное практически очень сложно если нет обработчиков исключений


 
SLoW.AlfaMoon.Com   (2007-07-17 17:49) [27]

DVM
+1 разумеется


 
Инс ©   (2007-07-17 19:05) [28]

О, Рома :) Какая встреча!


> [23] SLoW.AlfaMoon.Com   (17.07.07 10:34)

Хм.. Что-то необъяснимое ты мне говоришь. Либо я с ума сошел под конец дня, либо в TThread поток создается с помощью BeginThread, которая в любом случае заключает тело потока в SEH-фрейм.


 
slow.alfamoon.com   (2007-07-18 11:10) [29]

я конечно не эксперт но скажу -  у нас были бааальшие проблемы именно из-за того что исключение вылетало в потоке и не ловилось. BeginThread я не копал, не знаю, но проблема есть.



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

Форум: "WinAPI";
Текущий архив: 2008.03.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.007 c
2-1203185365
guav
2008-02-16 21:09
2008.03.16
Хитрые структуры данных.


2-1203078103
alexsashkan
2008-02-15 15:21
2008.03.16
SQL запрос,умножение значений полей


2-1203124294
DJ_UZer
2008-02-16 04:11
2008.03.16
Цвет текста


2-1203455145
{RASkov}
2008-02-20 00:05
2008.03.16
MessageBox + MB_HELP


2-1203327368
mfender
2008-02-18 12:36
2008.03.16
Кодировка XML. Не могу осилить...





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