Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.95/125: Рейтинг темы: голосов - 125, средняя оценка - 4.95
1 / 1 / 0
Регистрация: 17.09.2008
Сообщений: 6

Потоки(TThread)

24.09.2008, 20:39. Показов 25731. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здраствуйте. У меня возникла следующая проблема, начал изучать потоки,когда создаю три потока, третий должен запуститься после окочания роботы одного из двух (наважно какой). вот тут ы проблема, Билдер выдаёт ошыбку типа неверный дискриптор. Как можно исправить ошыбку?
главный класс
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
TForm1 *Form1;
mynP1 *thr_1;//поток 1
mynP2 *thr_2;//поток 2
myP3 *thr_3;//поток 3
void __fastcall TForm1::btnStartThreadsClick(TObject *Sender)
{
thr_1=new mynP1(true); 
thr_2=new mynP2(true);
thr_3=new myP3(true);
//thr_1->Priority=tpIdle;
//thr_2->Priority=tpIdle;
thr_1->FreeOnTerminate=true;
thr_2->FreeOnTerminate=true;
thr_3->FreeOnTerminate=true;
switch(RadioGroup1->ItemIndex)
{
case 0:{thr_1->Priority=tpIdle;thr_2->Priority=tpIdle;}break;
case 1:{thr_1->Priority=tpHigher;thr_2->Priority=tpHigher;}break;
case 2:{thr_1->Priority=tpHighest;thr_2->Priority=tpHighest;}break;
default : {thr_1->Priority=tpNormal;thr_2->Priority=tpNormal;}break;
}
thr_1->Resume();
thr_2->Resume();
thr_3->Resume();
}
поток 3:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
extern mynP2 *thr_2;
void __fastcall myP3::Execute()
{
        //---- Place thread code here ----
thr_2->WaitFor();//ожыдаем его завершения
summ3=0;
for(int i=0;i<=10000;i++)
{
//Application->ProcessMessages();
//Form1->ProgressBar1->Position=i;
summ3+=i-sin(i*M_PI/180);
}
 Form1->Memo1->Lines->Add("P3:"+ FloatToStr(summ3));
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.09.2008, 20:39
Ответы с готовыми решениями:

Потоки, TThread, нет синхронизации
Доброго дня, товарищи программисты. Проблемка тут у меня с потоком. Я создаю поток, делаю там делишки хорошие, потом нажимаю на кнопицу...

TThread, TThread, TThread .......... %)
помогите, если не затруднит как можно динамически создать поток и передать ему выполнение чего-либо например:...

Клас TThread
Нужно написать програму для реализации потоков через клас TThread. Когда я создаю этот клас, билдер автоматически создает конструктор и...

15
 Аватар для Vovan-VE
13210 / 6599 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
25.09.2008, 18:24
Из потоков обращаться напрямую к форме и тем более к ее компонентам - это очень плохая идея. Я в таких случаях посылаю форме свои мессаги с нужными параметрами.
0
1 / 1 / 0
Регистрация: 17.09.2008
Сообщений: 6
25.09.2008, 19:55  [ТС]
Да, я с вами соласен, можно либо использовать Synhronize() либо посылать сообщения, но согласно задания использоваиня VCL компонент в программе - допускаеться. Мне важно как правильно в моём случае использовать ф-ю WaitFor?
0
 Аватар для Vovan-VE
13210 / 6599 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
26.09.2008, 07:23
WaitFor() ждет пока поток не совсем не завершится. Если она никак не может дождаться, то это значит, что второй поток не завершается. Можно код второго потока?
0
1 / 1 / 0
Регистрация: 17.09.2008
Сообщений: 6
26.09.2008, 15:02  [ТС]
код второго потока:
C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall mynP2::Execute()
{
summ=0;
for(int i=0;i<=10000;i++)
{
//Application->ProcessMessages();
//Form1->ProgressBar1->Position=i;
summ+=sin(i*M_PI/180);
}
 Form2->Memo2->Lines->Add("P2:"+ FloatToStr(summ));
}
Такую же ошибку можно вызвать, если после завершения роботы потока, вызвать метод Suspend() етого потока. Возможно я не там прописал WaitFor()? или метод Resume третьего потока надо запускать в другом месте?
0
 Аватар для Vovan-VE
13210 / 6599 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
26.09.2008, 16:14
А может третий поток надо запускать раньше, чем второй? Может второй уже успевает сделать Free()?
0
1 / 1 / 0
Регистрация: 17.09.2008
Сообщений: 6
26.09.2008, 16:50  [ТС]
ксожалению третий должен начать роботать только после завершения второго (такое задание). И как раз для етого есть ф-я WaitFor(). Она, как мне кажеться ждёт когда закончит роботу один поток и запускает следующий.(я делал ету програму по примеру из книги Архангельского)
0
 Аватар для Vovan-VE
13210 / 6599 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
26.09.2008, 21:28
Нет, я имел ввиду вот это:
C++
1
2
3
4
5
}
thr_1->Resume();
thr_2->Resume();
thr_3->Resume();
}
Запустить сначала третий, а потом второй.
C++
1
2
3
4
5
}
thr_1->Resume();
thr_[b]3[/b]->Resume();
thr_[b]2[/b]->Resume();
}
Все равно третий не начнет работать раньше второго.
0
1 / 1 / 0
Регистрация: 17.09.2008
Сообщений: 6
27.09.2008, 19:47  [ТС]
я тоже пробовал тоже так делать- все одно таже ошибка. Сейчас переделал слегка прогу тепер после окончания одного потока сразу запускаю следюший(в методе Execute). Но все одно непонимаю как запустить поток методом WaitFor? Vovan-VE может вы использовали етот метод WaitFor или маете пример с ним? Просто из-за принцыпа интересно как же с ним роботать
0
 Аватар для Vovan-VE
13210 / 6599 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
27.09.2008, 22:07
Вообще с потоками почти всегда такая муть. Как ни крути-мути, все равно бывают случаи с ошибками.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
25.11.2009, 11:07
Цитата Сообщение от Vovan-VE Посмотреть сообщение
Из потоков обращаться напрямую к форме и тем более к ее компонентам - это очень плохая идея. Я в таких случаях посылаю форме свои мессаги с нужными параметрами.
Почему? Вот тут написано следующее:

Другая отличительная черта класса TThread — это гарантия безопасной работы с библиотекой визуальных компонентов VCL. Без использования класса TThread во время вызовов VCL могут возникнуть ситуации, требующие специальной синхронизации (см. разд. "Проблемы при синхронизации потоков" далее в этой главе).
Насколько я понимаю, класс разрабатывался именно с тем свойством, чтобы можно было из потоков напрямую обращаться к компонентам формы. Или за этой фразой кроется какой-то другой смысл?

Добавлено через 47 минут
Хотя далее написано про Synchronize. Видимо это оно и есть
0
43 / 39 / 12
Регистрация: 05.01.2009
Сообщений: 394
25.11.2009, 16:15
если нужно понять как устроены классы VCL то удобно смотреть исходники на делфи!
вот например процедура Synchronize
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
       TThreadMethod = procedure of object;
 
 PSynchronizeRecord = ^TSynchronizeRecord;
  TSynchronizeRecord = record
    FThread: TObject;
    FMethod: TThreadMethod;
    FSynchronizeException: TObject;
  end;
 
 
 
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord);
var
  SyncProc: TSyncProc;
begin
  if GetCurrentThreadID = MainThreadID then
    ASyncRec.FMethod
  else
  begin
{$IFDEF MSWINDOWS}
    SyncProc.Signal := CreateEvent(nil, True, False, nil);
    try
{$ENDIF}
{$IFDEF LINUX}
      FillChar(SyncProc, SizeOf(SyncProc), 0);  // This also initializes the cond_var
{$ENDIF}
      EnterCriticalSection(ThreadLock);
      try
        if SyncList = nil then
          SyncList := TList.Create;
        SyncProc.SyncRec := ASyncRec;
        SyncList.Add(@SyncProc);
        SignalSyncEvent;
        if Assigned(WakeMainThread) then
          WakeMainThread(SyncProc.SyncRec.FThread);
{$IFDEF MSWINDOWS}
        LeaveCriticalSection(ThreadLock);
        try
          WaitForSingleObject(SyncProc.Signal, INFINITE);
        finally
          EnterCriticalSection(ThreadLock);
        end;
{$ENDIF}
{$IFDEF LINUX}
        pthread_cond_wait(SyncProc.Signal, ThreadLock);
{$ENDIF}
      finally
        LeaveCriticalSection(ThreadLock);
      end;
{$IFDEF MSWINDOWS}
    finally
      CloseHandle(SyncProc.Signal);
    end;
{$ENDIF}
    if Assigned(ASyncRec.FSynchronizeException) then raise ASyncRec.FSynchronizeException;
  end;
end;
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
25.11.2009, 16:52
Про Synchronize я, если честно, толком не понял, как сие использовать

Добавлено через 55 секунд
Фенрир, а у тебя есть короткий пример, как задача в потоке на форму что-то отображает. А ещё я не понял, какие есть средства синхронизации. Для потоков в линухе используются mutex'ы, а что в винде?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
25.11.2009, 20:53
Ещё вопрос. Создаю программу примерно по следующей схеме. Как в примерах создаю производный класс, устанавливаю в конструкторе FreeOnTerminate в true, а в конце процедуры Execute ещё и на всякий случай "delete this" написал.

В программе работает таймер с интервалом в 1 секунду. На каждую активацию таймера создаю новый процесс, который исполняется, что-то там себе считает и выходит. На всё это уходит заведомо меньше секунды. Получается так, что каждую секунду я создаю новый поток. При запуске из IDE в информационной строке мне об этом постоянно сообщается, т.е. на каждый созданный поток печатается строка, что создался новый поток (Thread Start: Thread ID: ....). И вроде бы по такой логике поток при завершении работы метода Execute должен удаляться. Однако если погонять программу несколько секунд, после чего закрыть программу, то в информационном окне IDE вылезает целая пачка сообщений (Thread Exit: Thread ID: ....). Что это означает? Что потоки реально не были удалены или это какие-то особенности запуска из-под IDE? Запускаю в Release-версии, т.е. вроде бы как без отладчика должно?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
06.12.2009, 17:58
Цитата Сообщение от Evg Посмотреть сообщение
Ещё вопрос. Создаю программу примерно по следующей схеме. Как в примерах создаю производный класс, устанавливаю в конструкторе FreeOnTerminate в true, а в конце процедуры Execute ещё и на всякий случай "delete this" написал.

В программе работает таймер с интервалом в 1 секунду. На каждую активацию таймера создаю новый процесс, который исполняется, что-то там себе считает и выходит. На всё это уходит заведомо меньше секунды. Получается так, что каждую секунду я создаю новый поток. При запуске из IDE в информационной строке мне об этом постоянно сообщается, т.е. на каждый созданный поток печатается строка, что создался новый поток (Thread Start: Thread ID: ....). И вроде бы по такой логике поток при завершении работы метода Execute должен удаляться. Однако если погонять программу несколько секунд, после чего закрыть программу, то в информационном окне IDE вылезает целая пачка сообщений (Thread Exit: Thread ID: ....). Что это означает? Что потоки реально не были удалены или это какие-то особенности запуска из-под IDE? Запускаю в Release-версии, т.е. вроде бы как без отладчика должно?
Причина это кроется в том, что я реализовал так и этот самый delete и испортил картину. Правильно делать так
0
4 / 4 / 1
Регистрация: 28.11.2009
Сообщений: 6
06.12.2009, 18:28
А без WaitFor совсем не обойтись?
Можно навоять обработчик собыйти Thread->OnTerminate.
Присвоить его двум первым потокам. В обработчике создать проверку на то, что 3-й поток не запущен и в этом случае запустить его. Вот и всё шаманство.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.12.2009, 18:28
Помогаю со студенческими работами здесь

TThread и ShowMessage
Пискал ответ на проблему в гугле - вижу, что проблема довольно масштабная, т.к. у многих возникают вопросы. Единственная проблема - почти...

Несколько модулей TThread
Доброго времени суток! Подскажите, допускается ли создание несколько модулей TThread, а так же параллельная работа их методов Execute ? ...

TThread и копирование файлов
Добрый день спецы. Пишу достаточно сложную программу, точнее оптимизирую то, что было написано ранее. Необходимо создать поток который...

Tthread доступ к переменным
Здравствуйте, подскажите, пожалуйста, как использовать объявленную в потоке переменную в другом модуле?

TThread,Terminate() и Terminated
Как можно проверить остановлен ли поток и как остановить поток в версиях Builder-a начиная с 2009, версии ведь свойства Terminated нет...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru