Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Почему нельзя освободить память из-под потока? FreeOnTerminate = true --> исключение 
:(
    Опции темы
ksili
Дата 12.3.2007, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



У меня один коротенький поток вызывается главным окном каждые 2 секунды. Логично освобождать из-под него память. Однако если FreeOnTerminate = true,  то возникает исключение примерно такого содержания:
"... raised exception class EOSError with message 'System Error. Code: 6. Неверный дескриптор'". Прямо так по-русски и пишет - неверный дескриптор.
В классе потока есть три перменные, но я вроде к ним нигде кроме как из самого потока не обращаюсь, тем более после его завершения.
В чём может быть проблема?
Что это за класс EOSError?


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Vyacheslav
Дата 12.3.2007, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(ksili @  12.3.2007,  10:54 Найти цитируемый пост)
коротенький поток вызывается главным окном каждые 2 секунды.

А после того, как отрабатывает, Вы его заново создаете?




--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
ksili
Дата 12.3.2007, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Создаю его по событию таймера. Событие возникает каждые 3 секунды  (а не 2 как раньше написал, извиняюсь). За это время он успевает завершиться.

Но это наверно неважно, так как возникает исключение на первом же экземпляре потока (только не знаю именно в момент завершения или нет).

А вообще если он не успеет завершиться за 3 сек. И по таймеру будет создан второй поток, он не будет конфликтоватьс первым? Или это будет неправильно?

Это сообщение отредактировал(а) ksili - 12.3.2007, 11:13


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Vyacheslav
Дата 12.3.2007, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Без кода врядли что можно сказать путное


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
ama_kid
Дата 12.3.2007, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 10
Всего: 95



Код, конечно, в таких вопросах ОБЯЗАТЕЛЬНО надо приводить... Навскидку можно предположить, что при завершении потока вызывается последовательность Thread1->Terminate и затем Thread1->Free (или как-то аналогично). При установленном свойстве FreeOnTerminate = true вторая команда фактически будет освобождать уже автоматически особожденный (при Terminate) участок памяти, что приводит к AV.


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
ksili
Дата 12.3.2007, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Посмотрел в диспетчере задач без FreeOnTerminate = true. Вроде всё нормально один процесс создаётся и через некоторое время убивается. Память тоже освобождается и выделяется (больше не становится). Так что ложная тревога. Всем спасибо за внимание


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Vyacheslav
Дата 12.3.2007, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(ksili @  12.3.2007,  11:43 Найти цитируемый пост)
Посмотрел в диспетчере задач без FreeOnTerminate = true

А причем тут процессы smile Речь идет об уничтожении объекта класса после завершения процесса. То есть у Вас (если Вы конечно не уничтожаете  объект сами ) будет накапливаться утечка памяти.
Правда по завершению программы конечно все освободится ( WIn32 как никак smile ).  Но согласитесь, что такой подход некрасив : new без delete

Добавлено @ 13:21 
Цитата(ksili @  12.3.2007,  11:43 Найти цитируемый пост)
Память тоже освобождается и выделяется (больше не становится). 

Это Вы по диспетчеру задач определили ? Мда. А Вы не пробовали  спросить мнение на этот счет у CodeGuard? Думаю, он будет против. smile


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
ksili
Дата 13.3.2007, 05:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Так значит правильная последовательность работы с потоком примерно такая:
Код

td = new TDispThread(true);

td->hCom = All_chnls->chnls[i].pGSM;
td->Resume();

td->WaitFor();

delete td;

?

Если так написать, то память будет освобождаться и на флаг FreeOnTerminate можно не обращать внимание? Я правильно понял?

Это сообщение отредактировал(а) ksili - 13.3.2007, 07:37


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
pandrew
Дата 13.3.2007, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 213
Регистрация: 27.3.2006

Репутация: 3
Всего: 3



Для потока с FreeOnTerminate = true; завершение делается так:
Код

td->Terminate();
td->WaitFor();td=0;

Видимо если FreeOnTerminate = false; надо добавить delete td;
PM MAIL   Вверх
Vyacheslav
Дата 13.3.2007, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(ksili @  13.3.2007,  05:07 Найти цитируемый пост)
Так значит правильная последовательность работы с потоком примерно такая:

Идея то правильная.  И тут все будет очищаться правильно. Только в с логикой напряги.  Вы запускаете поток, а потом тормозите основной до момента, пока не выполнится дочерний. Смысл? Не проще тогда выполнить все действия в основном потоке? Все равно при работе дочернего он простаивает smile 
Я пока не могу понять одно. Почему у Вас не работает это ?
Код

td = new TDispThread(true);
td->FreeOnTerminate = true;
td->hCom = All_chnls->chnls[i].pGSM;
td->Resume();

Вы случаем после этих строчек не пытаетесь написать что-то вроде
Код

td->WaitFor();

или то, что  pandrew указал? Этого делать ни в коем случае нельзя. К моменту  обращения  к объекту td после того как уже вызван  Resume() поток может выполнится, а объект, соответственно, уничтожен  и Вы будете обращаться к несуществуещему объекту

Добавлено @ 13:17 
Цитата(pandrew @  13.3.2007,  10:27 Найти цитируемый пост)
Для потока с FreeOnTerminate = true; завершение делается так:

Грубая ошибка. Во-первых к моменту вызова Terminate поток может уже завершиться и td уничтожиться. Во-вторых, даже если поток еще работает, то он может успеть завершиться и уничтожиться после Terminate, но  до вызова  WaitFor.




--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
ksili
Дата 13.3.2007, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Сейчас уже кода перед глазами нет, завтра погляжу повнимательнее и отвечу.
А почему нельзя после Resume() писать WaitFor()? Когда вообще тогда WaitFor() писать нужно?


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
dumb
Дата 13.3.2007, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 32
Всего: 158



ksili, сможешь аргументировать применение потоков в своей задаче?

Цитата(F1(WaitFor))

Waits for the thread to terminate and then returns the value of the ReturnValue property.

PM MAIL   Вверх
ksili
Дата 14.3.2007, 05:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Я согласен, что WaitFor использовать в основном потоке неправильно, так как это тормозит всю прогу и сводит на нет все преимущество от использования потоков.

Теперь попробую аргументировать применение потоков в моей задаче.
В системе есть много COM-портов. Программа должна опрашивать те которые инициализированы (сейчас при отладке экспериментирую только с одним) на предмет того, что на них что-то поступило. Если поступило, то она сохраняет инфу об этом в специальной таблице БД. 
Есть ещё несколько потоков, которые периодически смотрят в эту таблицу и если там что-то есть, то отрабатывают это событие.

То событие таймера (раз в 3 сек)  о котором я говорил выше, перебирает все порты и запускает для каждого инициализированного порта поток, к-рый его опрашивает.

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

Я сейчас уже подумал, что правильнее будет не создавать эти потоки каждые 3 секунды, а создавать поток на каждый инициализированный порт, который будет его опрашивать постоянно:

Код

while(!Terminated)
    {
    ......
    }


Это сообщение отредактировал(а) ksili - 14.3.2007, 06:01


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Valeri
Дата 14.3.2007, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 2.2.2007

Репутация: нет
Всего: нет



Привет 
у меня примерно такая же задача, но порт всего один. смысл тот же - время от времени для передачи в порт данных требуется приостановить поток сбора данных из порта. 
Сделал поток именно так как указано в предыдущем посте. Но не пойму почему не удается подвесить поток на время передачи в порт. Программа виснет. 

сам поток в таком виде работает нормально:

while(!Terminated)
        {

               if(WaitCommEvent(Form1->hCom,&dwCommEvent,NULL))               

                if(ClearCommError(Form1->hCom,&dwError,&COMSTAT))
                    dwRead=COMSTAT.cbInQue;
                                  {
                                          while (dwRead)
                                       {
        ReadFile(Form1-hCom   lpBuffer1,dwRead,lpNumberOfBytesWritten, NULL);
                        
                        Form1->Nsect=Form1->Data.RecByte1
                        Form1->Fh=(Form1->Data.RecByte2)+((Form1->Data.RecByte3)*255);
                                        
                        Form1->Label20->Caption=IntToStr(Form1->Data.RecByte1);
                        Form1->Label21->Caption=IntToStr(Form1->Data.RecByte2);
                        Form1->Label23->Caption=IntToStr(Form1->Data.RecByte3);
                        Form1->Label24->Caption=IntToStr(Form1->Fh);
                          
                                         }
                                   }
        }

но при попытке его подвесить из основного потока все виснет. 

PM MAIL   Вверх
ksili
Дата 14.3.2007, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Всё, что обращается к основной форме

Цитата(Valeri @  14.3.2007,  14:09 Найти цитируемый пост)
                        
Form1->Nsect=Form1->Data.RecByte1
                        Form1->Fh=(Form1->Data.RecByte2)+((Form1->Data.RecByte3)*255);
                                        
                        Form1->Label20->Caption=IntToStr(Form1->Data.RecByte1);
                        Form1->Label21->Caption=IntToStr(Form1->Data.RecByte2);
                        Form1->Label23->Caption=IntToStr(Form1->Data.RecByte3);
                        Form1->Label24->Caption=IntToStr(Form1->Fh);

надо поместить в отдельную функцию класса потока и вызывать её при помощи метода потока Synchronize. посмотри хелп на Synchronize


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Valeri
Дата 14.3.2007, 09:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 2.2.2007

Репутация: нет
Всего: нет



Так ведь Synchronize нужна, чтобы предотвратить одновременный доступ к одному и тому же объекту. В моей программе только поток чтения обращается к объектам

Form1->Nsect=Form1->Data.RecByte1
                        Form1->Fh=(Form1->Data.RecByte2)+((Form1->Data.RecByte3)*255);
                                        
                        Form1->Label20->Caption=IntToStr(Form1->Data.RecByte1);
                        Form1->Label21->Caption=IntToStr(Form1->Data.RecByte2);
                        Form1->Label23->Caption=IntToStr(Form1->Data.RecByte3);
                        Form1->Label24->Caption=IntToStr(Form1->Fh); 



, а чтобы не случилось проблем я и пытаюсь притормаживать поток чтения.
PM MAIL   Вверх
ksili
Дата 14.3.2007, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Synchronize нужна всегда, когда обраащешься к визуальным компонентам (Form, Label и т.д.) потому что есть ещё основной поток твоей программы, и когда он там к чему обратится неизвестно (событий же куча). Поэтому надо синхронизировать. Попрбуй сделать как я написал, может висяки исчезнут.
Да и здесь на форуме есть несколько тем, где это более-менее описано. А к данной теме синхронизация очень отдалённо относится


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Valeri
Дата 14.3.2007, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 2.2.2007

Репутация: нет
Всего: нет



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

Фишка еще вот в чем -
когда убираю функции Suspend и Resume, то все работает нормально - и чтение идет и запись, но как-то это не красиво: при записи в порт надо остановить чтение. Пока не придумал как.
PM MAIL   Вверх
Vyacheslav
Дата 14.3.2007, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(ksili @  13.3.2007,  13:20 Найти цитируемый пост)
А почему нельзя после Resume() писать WaitFor()? Когда вообще тогда WaitFor() писать нужно? 

Если Вы используете FreeOnTerminate = true, то после Resume() вообще обращаться к как либо к объекту TThread  обращаться  опасно. К тому времени, когда Вы  попытаесь обратиться, вполне возможно, что он уже завершился и в о

Цитата

Warning:    When FreeOnTerminate is true, the Execute method may run and then free the thread before your application can execute the next line of code. Thus, you should not call any methods of the thread object when FreeOnTerminate is true unless you create the thread in a suspended state.

Вольный перевод
Цитата

Предупрежение. Когда FreeOnTerminate  установлен в true,  Execute метод может быть уже сработать  и затем освободить поток до того как Ваше  приложение сможет выполнить следующую строчку кода. Поэтому Вы не должны вызывать любое методы объекта потока, когда FreeOnTerminate  установлен в true, за исключением случая, когда Вы создали поток в подвешанном состоянии.


Что касается использования  WaiteFor, то все очень просто.   WaitFor как раз должен следовать за Resume, но не следующей сточкой smile
Код

td = new TDispThread(true);
td->Resume();

// далаем что-то  основном потоке
// еще  что-то  делаем  основном потоке
// и еще  что-то  делаем  основном потоке

// закончили делать и нам нужны результаты работы потока
// поэтому ждем завершения потока
td-> WaiteFor();
// здесь что-то делаем с результами работы потока

// при необходимости удаляем
delete td;  

То есть в отличие от вашего кода мы имеем участок, когда идет паралельное выполнение в основном и дочернем потоке. А WaiteFor() в данном случае приминяется для синхронизации этих потоков. Мы же не знаем, кто завершит свой код раньше основной поток или дочерний. Но такое поведене справедливо при FreeOnTerminate= false



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
pandrew
Дата 14.3.2007, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 213
Регистрация: 27.3.2006

Репутация: 3
Всего: 3



Цитата(Vyacheslav @  13.3.2007,  13:09 Найти цитируемый пост)
Добавлено @ 13:17 
Цитата(pandrew @  13.3.2007,  10:27 )
Для потока с FreeOnTerminate = true; завершение делается так:

Грубая ошибка. Во-первых к моменту вызова Terminate поток может уже завершиться и td уничтожиться. Во-вторых, даже если поток еще работает, то он может успеть завершиться и уничтожиться после Terminate, но  до вызова  WaitFor.


Читаем: 
TThread::Terminate
Signals the thread to terminate by setting the Terminated property

Так что утверждение про разрушение td между вызовами сомнительно.
Я всегда пишу потоки как бесконечную петлю обработки (иначе не понимаю зачем они нужны), поэтому самозавершения потоков у меня не бывает. Бывают правда исключение в потоковой функции, которые приводят к завершению, если не обрабатываются. Но я всегда рулю всеми потоками из главного без проблем по указанному варианту.
В вашей логике те же грабли: любой вызов td может быть некорректен, ибо td уже разрушен
PM MAIL   Вверх
Vyacheslav
Дата 14.3.2007, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(pandrew @  14.3.2007,  18:10 Найти цитируемый пост)
Читаем: 
TThread::Terminate
Signals the thread to terminate by setting the Terminated property

Так что утверждение про разрушение td между вызовами сомнительно.
Я всегда пишу потоки как бесконечную петлю обработки (иначе не понимаю зачем они нужны), поэтому самозавершения потоков у меня не бывает. Бывают правда исключение в потоковой функции, которые приводят к завершению, если не обрабатываются. Но я всегда рулю всеми потоками из главного без проблем по указанному варианту.
В вашей логике те же грабли: любой вызов td может быть некорректен, ибо td уже разрушен 

Причем тут это? Вы вводную читали?
Цитата(ksili @  12.3.2007,  11:08 Найти цитируемый пост)
Создаю его по событию таймера. Событие возникает каждые 3 секунды  (а не 2 как раньше написал, извиняюсь). За это время он успевает завершиться

Поток успевает завершиться сам, а не принудительно через Terminate. И таких задач, где нет бесконечного цикла  навалом. Если Вы не встречали в своей практике, это еще не значит, что их нет. 
Так что Ваш код для данного случаЯ ошибочен. Поток во-первых может завершиться сам до вызова Terminate. 
Ну а если Вы этот же код используете у себя и при этом у вас есть цикл с проверкой Terminated и FreeOnTerminate == true, то код  

Код

td->Terminate();
td->WaitFor();td=0;

опасен все равно. Потому что есть вероятность, что Вы можете схлопотать эксепшен на вызове WaitFor(). Надеяться на то, что между вызовами Terminate и WaitFor объект не успеет разрушится, неразумно. Если уж очень хочется обнулить td то логичнее и безопаснее смотрелось бы
 
Код

td->Terminate();
td=0;


smile
 
 



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
ksili
Дата 15.3.2007, 05:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



У меня основной целью было не обнулить td, а чтобы не росла занимаемая программой память из-за постоянно создаваемых потоков.
В принципе я уже переделал основные потоки, к-рые создаются моей программой, по типу бесконечной петли обработки, но есть ещё поток, который создаётся время от времени.
 
О, прямо сейчас придумал! А если и этот поток делать как бесконечную петлю обработки, но, поскольку он должен выполняться эпизодически, ввести дополнительное условие:
Код

while(!Terminated)
    {
     if(flag)
        {
         .....
        }
    }

А флаг просто менять из того потока, который должен активировать этот


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
dumb
Дата 15.3.2007, 07:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 32
Всего: 158



Цитата(ksili @  15.3.2007,  05:30 Найти цитируемый пост)
О, прямо сейчас придумал!

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

твой поток можно сделать, например, так:
Код

  HANDLE hEvent = CreateEvent(0,0,0,"vasya");
  while(!Terminated)
  {
    WaitForSingleObject(hEvent, INFINITE);
    ...
  }
  CloseHandle(hEvent);


когда нужно, чтобы рабочий поток выполнил "...", в основном потоке делаешь:
Код

  HANDLE hEvent = OpenEvent(0,0,"vasya");
  if (hEvent)
  {
    SetEvent(hEvent);
    CloseHandle(hEvent);
  }

PM MAIL   Вверх
ksili
Дата 15.3.2007, 07:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Да, суть та же, только писанины больше. Всё равно же, все эти апишные функции (как впрочем и все), по сути - обёртки для обычных mov eax, ecx  smile (в нашем случае - mov flag, 1). А, по-моему, чем проще, тем надёжнее и быстрее


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0696 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.