C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
ПОтоки, процессы, синхронизация., Нужет готовый исходник.
Green
Отправлено: 17.01.2005, 07:30


Не зарегистрирован







Нужно создать многопоточное приложение. И продемострировать синхронизацию. У кого нибудь есть что-то подобное?
Приложение создал(три потока), а вот с синхронизацией проблемы.
Вот увижу рабочий код, пойму как ее(синхронизацию) организовывать.
Помогите.
Doga
Отправлено: 17.01.2005, 12:14


Мастер участка

Группа: Участник
Сообщений: 575



https://rxlib.ru/forums/index.php?ac...e3eab6e29e27154


Или поиск по форуму smile.gif
Георгий
Отправлено: 17.01.2005, 13:36


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



http://www.cbuilder.ru/WinLesson/bles2.htm
Тиграша
Отправлено: 01.03.2005, 08:55


Ученик-кочегар

Группа: Участник
Сообщений: 24



Чего-то я с потоками втупляю...
Есть TThread* TTh
CODE

void __fastcall TTh::Execute()
{
this->FreeOnTerminate = true;
while(!Terminated){
       if(Terminated){break;}//;-)
       Synchronize(Action);
}
}

Вызываю Th->Terminate();
И после этого всё-таки Th!=NULL.
Оч. хочется сделать Th=NULL.
Как сделать?

Отредактировано Тиграша — 01/03/2005, 09:15
Gedeon
Отправлено: 01.03.2005, 09:21


Ветеран

Группа: Модератор
Сообщений: 1742




CODE

Th->OnTerminate = ThTerminate; // Ваша ф-ция обработчик в юните вызова нити


void __fastcall TForm1::ThTerminate(TObject *Sender)
{
   Th=NULL;    
}
//---------------------------------------------------------------------------
Konstantine
Отправлено: 01.03.2005, 09:24


Мастер участка

Группа: Модератор
Сообщений: 545



ну не равен... а указатель можно и нулём сделать пока процесс работает... ему ничё не будет — просо доступа к нему не будет и делов-то... поэтому сделали Terminate и не дожидаясь можно обнулить — если уверены, что процесс завершиться нормально
Тиграша
Отправлено: 01.03.2005, 09:32


Ученик-кочегар

Группа: Участник
Сообщений: 24



2Konstantine — Мне же именно хочется в вызывающем приложении дождаться нормального завершения части потоков.
А как я узнаю, что объекты delete корректно?
2Gedeon — Th=NULL; Странно... Мне кажется такое — не в русле идеологии TThread cool.gif Они вроде бы для того и сделали Terminate...

Отредактировано Тиграша — 01/03/2005, 09:42
Gedeon
Отправлено: 01.03.2005, 09:51


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (Тиграша @ 01/03/2005, 07:32)
Мне же именно хочется в вызывающем приложении дождаться нормального завершения части потоков.

Для этого и есть событие OnTerminate.
QUOTE

А как я узнаю, что объекты delete корректно?

Как напишите код, так они и delete, еще отладчик помогает.
QUOTE

2Gedeon — Th=NULL;  Странно... Мне кажется такое — не в русле идеологии TThread  cool.gif Они вроде бы для того и сделали Terminate...

Что не в русле? Присвоение указателю значения NULL? biggrin.gif .
Terminate сделан для того, чтобы установить флаг завершения потока, к-рый между прочим Вы должны отслеживать и поток завершать.
Bond
Отправлено: 01.03.2005, 10:38


Станционный диспетчер

Группа: Участник
Сообщений: 142



Вообще-то не политкоректно рабочему указателю присваивать значение NULL.
Даже если мы уверены что он не используется, тогда зачем?
Guest
Отправлено: 01.03.2005, 10:59


Не зарегистрирован







QUOTE
Вообще-то не политкоректно рабочему указателю присваивать значение NULL.

А в таком аспекте:
CODE

if (!FSubForm) TFSubForm = new TFSubForm(Application);
try {
FSubForm->Visible = false;
...
FSubForm->ShowModal();
...
}
catch (Exception &xcp) { ShowMessage(xcp.Message); }

delete FSubForm;
FSubForm = NULL;
Bond
Отправлено: 01.03.2005, 11:11


Станционный диспетчер

Группа: Участник
Сообщений: 142



QUOTE
Th->OnTerminate = ThTerminate; // Ваша ф-ция обработчик в юните (1) вызова нити


void __fastcall TForm1::ThTerminate(TObject *Sender)
{
  Th=NULL;    // (2)
}


(2) — обнуливается указатель в функции, которая была вызвана по этому указателю (1)


а тут
QUOTE
delete FSubForm;
FSubForm = NULL;
указатель обнуливается сразу после явного освобождения памяти.
Это даже необходимо делать для возможности проверить позже, была ли освобождена память из-под него — что парирует неккоректное обращение к освобожденной ранее памяти
Gedeon
Отправлено: 01.03.2005, 11:37


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (Bond @ 01/03/2005, 08:38)
Вообще-то не политкоректно рабочему указателю присваивать значение NULL.
Даже если мы уверены что он не используется, тогда зачем?

1) Вообщето об этом вопрошал автор топика.
2) Проверять пустой ли указатель для создания/несоздания новой нити.(зависит от логики программы).
3) Дабы не обратиться к уже уничтоженному обьекту.

QUOTE

TThread::OnTerminate
Occurs after the thread's Execute method has returned and before the thread is destroyed.

Да, нить еще не уничтожена, но будет по завершении данной функции, что плохого если тут присвоить указателю 0?
Как по другому Вы предлагаете это делать?

Отредактировано Gedeon — 01/03/2005, 09:40
Тиграша
Отправлено: 01.03.2005, 11:47


Ученик-кочегар

Группа: Участник
Сообщений: 24



Спрашивал я собственно о том, как корректно уничтожить TThread* Th. OnTerminate у меня есть, проверил — выполняется по Terminate(), а Th — всё равно не NULL

Отредактировано Тиграша — 01/03/2005, 11:49
Bond
Отправлено: 01.03.2005, 11:53


Станционный диспетчер

Группа: Участник
Сообщений: 142



Борландовский компиллер (не знаю на счет остальных) после выполнения операции delete Ptr; не задает указателю Ptr значение NULL
Тиграша
Отправлено: 01.03.2005, 12:08


Ученик-кочегар

Группа: Участник
Сообщений: 24



И что же мне бедному делать?
Message в главный объект слать, что каждый нужный поток выполнил OnTerminate и тогда уже делать Th = NULL?
Gedeon
Отправлено: 01.03.2005, 13:14


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (Bond @ 01/03/2005, 09:53)
Борландовский компиллер (не знаю на счет остальных) после выполнения операции delete Ptr; не задает указателю Ptr значение NULL

А какой компилятор это делает?
При чем тут вообще компилятор?
При удалении указателю нигде в ++ ноль не присваивается, кстати в дэлфи тоже.

2Тиграша
Делайте так, как я написал, что Вас не устраивает?

Отредактировано Gedeon — 01/03/2005, 11:15
Gedeon
Отправлено: 01.03.2005, 13:19


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (Тиграша @ 01/03/2005, 09:47)
Спрашивал я собственно о том, как корректно уничтожить TThread* Th. OnTerminate у меня есть, проверил — выполняется по Terminate(), а Th — всё равно не NULL

Если стоит FreeOnTerminate = true; поток корректно уничтожится.
Th — всё равно NULL не будет без явного присвоения. Если надо чтоб был 0 только для этой проверки — это неправильно.
Если хочется проверить все ли удаляется — CodeGuard.
Тиграша
Отправлено: 01.03.2005, 13:29


Ученик-кочегар

Группа: Участник
Сообщений: 24



Не, Gedeon, всё-таки я тебя не понял.
Смотри — из главной формы вроде бы плохо обнулять указатель — а мало ли что там с объектом происходит, а у меня пара объектов вообще без исходов, и что они там делают — я точно и не знаю.
В какой момент-то это делать?
Поторюсь — мне по сути надо корректно дождаться завершения некоторых TThread.
Если тебе не в лом — можж я для примеру один сырец выложу — посмотришь?
P.S. Я сегодня чего-то увольняться собрался, так что некогда пока, но вроде бы дело пошло — оч.хитёр один объект у меня, пытается оставить в системе "внука" cool.gif Так что спасибо all за обсуждение.

Отредактировано Тиграша — 02/03/2005, 12:39
Bond
Отправлено: 01.03.2005, 13:38


Станционный диспетчер

Группа: Участник
Сообщений: 142



1. delete — кажется является служебным словом, кое обрабатывает компилятор (зачем так жестко). Я просто уточнил.

2. Если неизвестно что делают thread-ы — указатель нельзя обнуливать. Можно ввсети флаги или еще что-то и их обрабатывать в OnTerminate
Konstantine
Отправлено: 01.03.2005, 13:55


Мастер участка

Группа: Модератор
Сообщений: 545



дождаться можно методом WaitFor()
Gedeon
Отправлено: 01.03.2005, 14:16


Ветеран

Группа: Модератор
Сообщений: 1742



ну кстати это идея, по поводу присвоения 0, ну конечно если неизвестно, то нельзя, все безусловно от логики зависит.
2Тиграша
выкладывайте, от чего б не посмотреть.
Gedeon
Отправлено: 01.03.2005, 14:54


Ветеран

Группа: Модератор
Сообщений: 1742



Вот кстати обсуждалось
Указатель на обьект. Живой или мертвый.
Тиграша_
Отправлено: 04.05.2005, 06:19


Не зарегистрирован







Всё-таки забавный зверёк этот TThread cool.gif
Столкнулся:
есть TForm* MainForm, которая создаёт 2 штуки TThread с нормальными приоритетами, которые начинают общаться между собой. И MainForm по идее должна быть управляющей для этих TThread. Всё нормально до тех пор, пока потоки обмениваются данными с MainForm достаточно быстро. Но в случае массированных вычислений в потоках, когда растёт время выполнения функции из Synchronize-ов, теряю smile.gif MainForm — никак не могу её сделать активной...
Есть а All соображения как побеждать?
Rius
Отправлено: 04.05.2005, 06:41


Мастер участка

Группа: Участник
Сообщений: 321



Никогда ничего тяжелого из Synchronize не вызывать. Все считать в потоках, для того они и созданы.
Кстати, у Thread есть свойство FreeOnTerminate
Тиграша
Отправлено: 04.05.2005, 12:45


Ученик-кочегар

Группа: Участник
Сообщений: 24



Забодал путём вставки в Synchronize Application->ProcessMessages(); wink.gif
А можно как-нибудь ещё бодать?

Вернуться в Вопросы программирования в C++Builder