Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++ Builder
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 44, средняя оценка - 4.95
Lionella
2 / 2 / 0
Регистрация: 01.10.2012
Сообщений: 15
Завершенные тесты: 1
#1

Пример простого многопоточного приложения - C++ Builder

07.02.2013, 15:09. Просмотров 6757. Ответов 10
Метки нет (Все метки)

Добрый день.

Пытаюсь реализовать пример из книги.

Итак, интерфейсный модуль, созданный мастером поточных объектов. В объявление класса TProThread добавлен член данных NT, аргумент конструктора заменен номером текущего потока Thread,и введена функция синхронизации ThreadProgress.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef ThreadUnit2H
#define ThreadUnit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
class TProThread : public TThread
{            
private:
        int NT;
protected:
        void __fastcall Execute();
public:
        __fastcall TProThread(int Thread);
        void __fastcall ThreadProgress();
};
//---------------------------------------------------------------------------
#endif
Переопределение метода Execute в кодовом модуле ThreadUnit2.cpp
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "ThreadUnit2.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
 
//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(UpdateCaption);
//
//   where UpdateCaption could look like:
//
//      void __fastcall TProThread::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//---------------------------------------------------------------------------
 
__fastcall TProThread::TProThread(int Thread)
        : TThread(false)
{
NT = Thread;
FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall TProThread::Execute()
{
while(!Terminated) Synchronize(ThreadProgress);
}
//---------------------------------------------------------------------------
void __fastcall TProThread::ThreadProgress()
{
Form1->pb[NT]->Position++;
if(Form1->pb[NT]->Position >= Form1->pb[NT]->Max)
   {
   Form1->sg->Cells[5][NT+1] = Form1->pbc[NT]++;
   Form1->pb[NT]->Position = 0;
   }
}
ThreadUnit.h

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
26
27
28
#ifndef ThreadUnitH
#define ThreadUnitH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TStringGrid *sg;
        TButton *Button1;
        TProgressBar *pb;
        void __fastcall Button1Click(TObject *Sender);
        void __fastcall sgSelectCell(TObject *Sender, int ACol, int ARow,
          bool &CanSelect);
private:    // User declarations
public:     // User declarations
        __fastcall TForm1(TComponent* Owner);
 
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

ThreadUnit.cpp
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
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <vcl.h>
#pragma hdrstop
#include "ThreadUnit2.h"
#include "ThreadUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
 
String tps[7] = {"Idle","Lowest", "Lower", "Normal","Higher","Highest",
                  "TimeCritical"};
bool tsb[1];
String tss[] = {"true", "false"};
int tpi[7];
int pbc[1];
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 
for(int i = 0;i < 8;i++)
   {tsb[i] = false; tss[i] = "false"; tpi[i] = 0; pbc[i] = 1;}
   sg->ColWidths[0] = 52;     sg->Cells[0][0] = "Thread";
   sg->ColWidths[1] = 68;     sg->Cells[1][0] = "ThreadID";
   sg->ColWidths[2] = 80;     sg->Cells[2][0] = "Suspended";
   sg->ColWidths[3] = 80;     sg->Cells[3][0] = "Priority";
   sg->ColWidths[4] = 280;    sg->Cells[4][0] = "Progress";
   sg->ColWidths[5]= 40;      sg->Cells[5][0] = "Pass";
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 
if(t < 8)
  {
ProThread[t] = new TProThread(1);
  sg->Cells[0][t+1] = IntToStr(t+1);
  sg->Cells[1][t+1] = IntToHex((int)ProThread[t]->ThreadID,8);
  sg->Cells[2][t+1] = tss[t];
  sg->Cells[3][t+1] = tps[tpi[t]];
  ProThread[t]->Priority = (TThreadPriority)tpi[t];
  pb[t] = new TProgressBar(sg);   pb[t]->Parent(sg);
  pb[t]->Left = 288;              pb[t]->Top = 27+23*t;
  pb[t]->Width = 272;             pb[t]->Height = 16;
  pb[t]->Max = 10000;
  sg->Cells[5][t+1] = pbc[t];     t++;
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::sgSelectCell(TObject *Sender, int ACol, int ARow,
      bool &CanSelect)
{
 
int r = ARow - 1;
if(t <= r) return;
if(ACol == 2)
   {
   if(tsb[r])
   {tsb[r] = false; tss[r] = "false";}
   else
   {tsb[r] = true; tss[r] = "true";}
   ProThread[r]->Suspended = tsb[r];
   sg->Cells[2][ARow] = tss[r];
   }
if(ACol == 3)
   {
   tpi[r]++;
   if(tpi[r] > 6) tpi[r] = 0;
   ProThread[r]->Priority = (TThreadPriority)tpi[r];
   sg->Cells[3][ARow] = tps[tpi[r]];
   }
}

Ошибки:
[C++Error] ThreadUnit.cpp 2451 Undefinite symbol `t`
[C++Error] ThreadUnit.cpp 2451 Undefinite symbol `ProThread`
[C++Error] ThreadUnit.cpp 2451 Undefinite symbol `t`
[C++Error] ThreadUnit.cpp 2451 Undefinite symbol `ProThread

Эту переменную t куда только не ставила. Если ее объявить глобальной, то ошибок вылезает полтора десятка...
http://www.cyberforum.ru/cpp-builder/thread1389987.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.02.2013, 15:09
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Пример простого многопоточного приложения (C++ Builder):

Помогите с компиляцией *.exe файла простого приложения
Всех приветствую и прошу помочь разобраться с проблемой. Я недавно начал...

GUI через c++ builder для простого консольного приложения
Есть вот такая простая консольная программа,помогите запилить GUI через C++...

Реализовать выход из многопоточного приложения при нажатии сочетания клавиш "Ctrl+С"
Добрый день! Подскажите пжл, как реализоввать выход с...

Создание простого приложения для Windows 9x/NT, решил как смог. Пожалуйста подскажите что исправить или добавить
задание: окно фон зелёный размер 500х400 курсор...

C++ и WinAPI - пример простого приложения
Можете дать пример простого приложения, которое будет выводить текст в окне...

10
Maluda
1217 / 549 / 104
Регистрация: 18.08.2009
Сообщений: 783
Завершенные тесты: 1
07.02.2013, 17:17 #2
Lionella, зачем лезть в потоки, если ты основу основ не понимаешь, не понимаешь, что такое области видимости, как объявляются переменные? Также, наверняка не понимаешь, что такое класс.
Не понимаешь, что TForm - это класс. void __fastcall TForm1::Button1Click(TObject *Sender) - это функция член класса. Следовательно, если в этой функции инициализируется ProThread[t] = new TProThread(1);,а его определения в cpp файле нет, значит скорее всего в твоей книге учебнике он объявлен тоже членом класса.

файл h
C++
1
2
3
4
5
6
7
8
class TForm {
private:
    // переменные являются закрытыми членами класса
    int t;
    TProThread *ProThread;
public:
    void __fastcall Button1Click(TObject *Sender);
}
файл cpp
C++
1
2
3
4
5
void __fastcall TForm::Button1Click(TObject *Sender) {
        if (t<8) {
        ProThread = new TProThread(1);
    }
}
Добавлено через 2 минуты
Вариант 2

файл h
C++
1
2
3
4
5
class TForm {
private:    
public:
    void __fastcall Button1Click(TObject *Sender);
}
файл cpp
C++
1
2
3
4
5
6
7
8
9
// переменные определены в cpp файле и являются глобальными по отношению ко всему коду,
// который расположен ниже в cpp файле
    int t = 0;
    TProThread *ProThread = 0;
void __fastcall TForm::Button1Click(TObject *Sender) {
    if (t<8) {
        ProThread = new TProThread(1);
    }
}
1
Lionella
2 / 2 / 0
Регистрация: 01.10.2012
Сообщений: 15
Завершенные тесты: 1
07.02.2013, 17:46  [ТС] #3
Цитата Сообщение от Maluda Посмотреть сообщение
Lionella, зачем лезть в потоки, если ты основу основ не понимаешь, не понимаешь, что такое области видимости, как объявляются переменные? Также, наверняка не понимаешь, что такое класс.
Не понимаешь, что TForm - это класс. void __fastcall TForm1::Button1Click(TObject *Sender) - это функция член класса. Следовательно, если в этой функции инициализируется ProThread[t] = new TProThread(1);,а его определения в cpp файле нет, значит скорее всего в твоей книге учебнике он объявлен тоже членом класса.
Что Вы, я не лезу в потоки. Просто пытаюсь ориентироваться, т.к. вдруг захотелось узнать побольше о программировании и С++ в частности, для начала. Использую то, что есть, в данном случае книгу Шамиса. Бобровского уже поизучала. Что такое класс - я в курсе, НО.. опыта маловато. А желание огромное, и, думаю, мне не стоит этим пренебрегать.
Back to topic, все равно ошибки.
0
Maluda
1217 / 549 / 104
Регистрация: 18.08.2009
Сообщений: 783
Завершенные тесты: 1
07.02.2013, 18:08 #4
Лучший ответ Сообщение было отмечено как решение

Решение

Lionella, заархивируй свой проект и выложи. Я отредактирую и скажу, в чём конкретно ошибка

Добавлено через 19 минут
Вот набросал тебе очень простой пример, думаю, что его легче будет понять

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
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
 
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
 
//---------------------------------------------------------------------------
class TMyThread : public TThread {
public:
 
    TMyThread(const bool CreateSuspended):TThread(CreateSuspended) {};
 
    void __fastcall Execute(void) {
        while (!this->Terminated) {
            Sleep(100);
            this->Synchronize(&UpdateCaption);
        }
    }
 
    void __fastcall UpdateCaption() {
        Form1->Caption = Now().DateTimeString();
    }
};
 
TMyThread *FMyThread = 0;
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
}
 
//---------------------------------------------------------------------------
void __fastcall TForm1::BtnStartClick(TObject *Sender) {
    if (FMyThread) {
        ShowMessage("Thread is already launched");
    }
    else {
        FMyThread = new TMyThread(false);
        FMyThread->FreeOnTerminate = false;
    }
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::BtnStopClick(TObject *Sender) {
    if (FMyThread) {
        FMyThread->Terminate();
        delete FMyThread;
        FMyThread = 0;
    }
}
//---------------------------------------------------------------------------
4
Lionella
2 / 2 / 0
Регистрация: 01.10.2012
Сообщений: 15
Завершенные тесты: 1
07.02.2013, 18:09  [ТС] #5
Цитата Сообщение от Maluda Посмотреть сообщение
Lionella, заархивируй свой проект и выложи. Я отредактирую и скажу, в чём конкретно ошибка
Ok, спасибо, я буду через полтора часа и выложу.
0
Maluda
1217 / 549 / 104
Регистрация: 18.08.2009
Сообщений: 783
Завершенные тесты: 1
07.02.2013, 18:09 #6
На форме две кнопки: одна запускает поток, вторая останавливает.
В потоке в заголовок формы выводится текущее время.
0
Lionella
2 / 2 / 0
Регистрация: 01.10.2012
Сообщений: 15
Завершенные тесты: 1
07.02.2013, 22:15  [ТС] #7
Проект
0
Вложения
Тип файла: rar ThreadAr.rar (8.6 Кб, 88 просмотров)
Maluda
1217 / 549 / 104
Регистрация: 18.08.2009
Сообщений: 783
Завершенные тесты: 1
08.02.2013, 14:33 #8
Понял, какая задача стояла: то есть по кнопке запустить 7 потоков с различным приоритетом.
По мере выполнения каждый поток должен обновлять соответствующий прогресс. Также необходимо остановить-возобновить работу потока и поменять приоритет.
Твой пример полностью переработал. Обрати внимание на структуру кода, на именование переменных,
на организацию комментариев и т.д.
Что непонятно будет, спрашивай.

ThreadUnit.cpp
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
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "ThreadUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
 
    // маркировка фиксированных ячеек таблицы
    GridThreadData->ColWidths[gctThreadNo] = 52;
    GridThreadData->Cells[gctThreadNo][0] = "Thread";
 
    GridThreadData->ColWidths[gctThreadId] = 68;
    GridThreadData->Cells[gctThreadId][0] = "ThreadID";
 
    GridThreadData->ColWidths[gctSuspend] = 80;
    GridThreadData->Cells[gctSuspend][0] = "Suspended";
 
    GridThreadData->ColWidths[gctPriority] = 80;
    GridThreadData->Cells[gctPriority][0] = "Priority";
 
    GridThreadData->ColWidths[gctProgress] = 80;
    GridThreadData->Cells[gctProgress][0] = "Progress";
 
    GridThreadData->ColWidths[gctPass] = 80;
    GridThreadData->Cells[gctPass][0] = "Pass";
 
    // создадим всплывающее меню, из которого можно будет приостановить поток
    // и поменять приоритет потока
    // ВЛАДЕЛЬЦЕМ УКАЗЫВАЕМ ФОРМУ, 
        // ПОЭТОМУ ПРИ ЗАВЕРШЕНИИ ПРОГРАММЫ ОНА САМА УДАЛИТ ЭТОТ КОМПОНЕНТ
    PopupMenu1 = new TPopupMenu(this);
 
    MenuSuspended = NewItem("Suspended", 0, false, true, &MenuSuspendedClick, 0, "MenuSuspended");
    PopupMenu1->Items->Insert(0, MenuSuspended);
 
    MenuChangepriority = NewItem("Change priority", 0, false, true, 0, 0, "MenuChangepriority");
    PopupMenu1->Items->Insert(0, MenuChangepriority);
 
    for (int i = 0; i < MAX_THREAD_COUNT; i++) {
        ProThread[i] = 0;
 
        TMenuItem *AMenuItem = NewItem(sThreadPriority[i], 0, false, true, &MenuPriorityItemClick,
            0, "Menu" + sThreadPriority[i]);
        AMenuItem->Tag = i;
        MenuChangepriority->Insert(i, AMenuItem);
    }
}
 
//---------------------------------------------------------------------------
void __fastcall TForm1::MenuSuspendedClick(TObject *Sender) {
 
    const int &iThreadId = MenuSuspended->Tag;
 
    if (ProThread[iThreadId]) {
        // если был остановлен - запускаем, а если запущен, приостанавливаем
        ProThread[iThreadId]->Suspended = !ProThread[iThreadId]->Suspended;
 
        GridThreadData->Cells[gctSuspend][iThreadId + 1] = BoolToStr
        (ProThread[iThreadId]->Suspended, true);
    }
    else {
        ShowMessage("Поток ещё не запущен");
    }
}
 
//---------------------------------------------------------------------------
void __fastcall TForm1::MenuPriorityItemClick(TObject *Sender) {
 
    const int &iThreadId = MenuChangepriority->Tag;
 
    if (ProThread[iThreadId]) {
        TMenuItem * AMenuItem = dynamic_cast<TMenuItem*>(Sender);
        if (AMenuItem) {
            // меняем приоритет согласно выбранному элементу в меню
            ProThread[iThreadId]->Priority = TThreadPriority(AMenuItem->Tag);
 
            GridThreadData->Cells[gctPriority][iThreadId + 1] = sThreadPriority[AMenuItem->Tag];
        }
    }
    else {
        ShowMessage("Поток ещё не запущен");
    }
}
 
//---------------------------------------------------------------------------
void __fastcall TForm1::BtnStartClick(TObject *Sender) {
    // флаг, который будет отвечать за то, что действие выполнено единоразово
    static bool bOnce = false;
    if (bOnce) {
        ShowMessage("Программа разрабатывалась для демо режима!"
 
            "\nРазрешается запустить потоки один раз!");
 
        return;
    }
 
    bOnce = true;
 
    // создадим и запустим потоки
    for (int i = 0; i < MAX_THREAD_COUNT; i++) {
        ProThread[i] = new TProThread(i);
        ProThread[i]->Priority = TThreadPriority(i);
 
        // создадим прогресс бар, который будет соответствовать потоку
        m_ProgressBarArray[i] = new TProgressBar(this);
        m_ProgressBarArray[i]->Parent = PanelContainer;
        m_ProgressBarArray[i]->Align = alTop;
        m_ProgressBarArray[i]->Max = 1000;  // величина побольше для наглядности
 
        // сделаем, чтобы прогрессы расположились правильно один над другим
        m_ProgressBarArray[i]->Top = i * m_ProgressBarArray[i]->Height + 3;
 
        // заполним ячейки таблицы данными о процессе
        GridThreadData->Cells[gctThreadNo][i + 1] = IntToStr(i + 1);
        GridThreadData->Cells[gctThreadId][i + 1] = IntToHex((int)ProThread[i]->ThreadID, 8);
        GridThreadData->Cells[gctSuspend][i + 1] = BoolToStr(ProThread[i]->Suspended, true);
        GridThreadData->Cells[gctPriority][i + 1] = sThreadPriority[ProThread[i]->Priority];
        GridThreadData->Cells[gctPass][i + 1] = "Started...";
    }
}
 
//---------------------------------------------------------------------------
 
void __fastcall TForm1::GridThreadDataMouseUp(TObject *Sender, TMouseButton Button,
    TShiftState Shift, int X, int Y) {
 
    if (Button == mbRight) {
 
        // получаем номер колонки и ряда ячейки
        const TGridCoord AGridCoord = GridThreadData->MouseCoord(X, Y);
 
        // щелчок по фиксированным ячейкам
        if (AGridCoord.X == 0 || AGridCoord.Y == 0) {
            return;
        }
 
        TGridRect AGridRect;
        AGridRect.TopLeft = AGridCoord;
        AGridRect.BottomRight = AGridCoord;
 
        // выделяем эту ячейку, так как по щелчку правой кнопки по умолчанию не выделяется
        GridThreadData->Selection = AGridRect;
 
        const TPoint APopupPoint = GridThreadData->ClientToScreen(TPoint(X, Y));
 
        // если щелчок в колонке, где можно приостановить поток, тогда делаем видимым этот пункт меню
        MenuSuspended->Visible = AGridRect.Left == gctSuspend;
        if (MenuSuspended->Visible) {
            const int &iThreadId = AGridRect.Top - 1;
 
            MenuSuspended->Tag = iThreadId;
            if (ProThread[iThreadId]) {
                MenuSuspended->Checked = ProThread[iThreadId]->Suspended;
            }
        }
 
        // если щелчок в колонке с выбором приоритета, тогда делаем видимым этот пункт меню
        MenuChangepriority->Visible = AGridRect.Left == gctPriority;
        if (MenuChangepriority->Visible) {
            const int &iThreadId = AGridRect.Top - 1;
 
            MenuChangepriority->Tag = iThreadId;
            if (ProThread[iThreadId]) {
                for (int i = 0; i < MenuChangepriority->Count; i++) {
                    MenuChangepriority->Items[i]->Checked =
                        MenuChangepriority->Items[i]->Tag == ProThread[iThreadId]->Priority;
                }
            }
        }
 
        // вызываем меню в координатах мыши в таблице
        PopupMenu1->Popup(APopupPoint.x, APopupPoint.y);
    }
}
 
//---------------------------------------------------------------------------
ThreadUnit.h
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
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
//---------------------------------------------------------------------------
 
#ifndef ThreadUnitH
#define ThreadUnitH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <Grids.hpp>
#include <ExtCtrls.hpp>
#include <Menus.hpp>
 
#include "ThreadUnit2.h"
 
//---------------------------------------------------------------------------
class TForm1 : public TForm {
__published: // IDE-managed Components
    TStringGrid *GridThreadData;
    TButton *BtnStart;
    TPanel *PanelContainer;
 
    void __fastcall BtnStartClick(TObject *Sender);
    void __fastcall GridThreadDataMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
        int X, int Y);
 
private:
    // массив-контейнер потоков
    TProThread *ProThread[MAX_THREAD_COUNT]; // User declarations
 
    // всплывающее меню, будет создано динамически в конструкторе
    TPopupMenu *PopupMenu1;
 
    TMenuItem *MenuSuspended;
    TMenuItem *MenuChangepriority;
 
    void __fastcall MenuSuspendedClick(TObject *Sender);
    void __fastcall MenuPriorityItemClick(TObject *Sender);
 
public: // User declarations
    __fastcall TForm1(TComponent* Owner);
 
    // массив-контейнер прогрессбаров, определен для общего доступа,
    // так как должен быть виден из другого класса ( TProThread )
    TProgressBar *m_ProgressBarArray[MAX_THREAD_COUNT];
};
 
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
ThreadUnit2.cpp
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
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "ThreadUnit.h"
 
#include "ThreadUnit2.h"
 
#pragma package(smart_init)
//---------------------------------------------------------------------------
 
//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(UpdateCaption);
//
//   where UpdateCaption could look like:
//
//      void __fastcall TProThread::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//---------------------------------------------------------------------------
 
__fastcall TProThread::TProThread(const int iThread) : TThread(false), m_i_CurrentThread(iThread) {
    FreeOnTerminate = true;
}
 
//---------------------------------------------------------------------------
void __fastcall TProThread::Execute() {
    while (!Terminated) {
        Synchronize(ThreadProgress);
        Sleep(16);
    }
}
 
//---------------------------------------------------------------------------
void __fastcall TProThread::ThreadProgress() {
    Form1->m_ProgressBarArray[m_i_CurrentThread]->Position++;
 
    const int iPercent = Form1->m_ProgressBarArray[m_i_CurrentThread]->Position * 100 /
        Form1->m_ProgressBarArray[m_i_CurrentThread]->Max;
 
    Form1->GridThreadData->Cells[gctProgress][m_i_CurrentThread + 1] = AnsiString(iPercent) + " %";
 
    if (Form1->m_ProgressBarArray[m_i_CurrentThread]->Position >= Form1->m_ProgressBarArray
        [m_i_CurrentThread]->Max) {
        Form1->GridThreadData->Cells[gctPass][m_i_CurrentThread + 1] = "Finished!";
        Form1->m_ProgressBarArray[m_i_CurrentThread]->Position = Form1->m_ProgressBarArray
        [m_i_CurrentThread]->Max;
        this->Terminate();
    }
}
ThreadUnit2.h
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
26
27
28
29
30
31
32
33
34
//---------------------------------------------------------------------------
 
#ifndef ThreadUnit2H
#define ThreadUnit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
 
// количество запускаемых потоков
#define MAX_THREAD_COUNT 7
 
// для удобства, чтобы не было путаницы промаркируем именами колонки в таблице
typedef enum {gctThreadNo, gctThreadId, gctSuspend, gctPriority, gctProgress, gctPass} TGridColumnType;
 
static String sThreadPriority[MAX_THREAD_COUNT] = {
    "Idle", "Lowest", "Lower", "Normal", "Higher", "Highest", "TimeCritical"
};
 
//---------------------------------------------------------------------------
class TProThread : public TThread
{            
private:
        // номер текущего потока
        const int m_i_CurrentThread;
        void __fastcall ThreadProgress();
protected:
        void __fastcall Execute();
public:
        __fastcall TProThread(const int iThread);
 
 
};
//---------------------------------------------------------------------------
#endif
1
Maluda
1217 / 549 / 104
Регистрация: 18.08.2009
Сообщений: 783
Завершенные тесты: 1
08.02.2013, 14:37 #9
Лучший ответ Сообщение было отмечено как решение

Решение

П.С. Делал всё в C++ Builder 2010. Исходник твоего проекта был сделан, наверное, в C++ Builder 6, его к сожалению установленного нет. Но думаю здесь всё предельно элементарно, поэтому разберёшься.

Брошу на всякий свой проект.

Должно на выходе получиться что-то вроде такого
4
Миниатюры
Пример простого многопоточного приложения   Пример простого многопоточного приложения  
Вложения
Тип файла: zip ThreadProj.zip (6.12 Мб, 162 просмотров)
Lionella
2 / 2 / 0
Регистрация: 01.10.2012
Сообщений: 15
Завершенные тесты: 1
26.02.2013, 23:57  [ТС] #10
Такое появляется после запуска программы:
0
Миниатюры
Пример простого многопоточного приложения   Пример простого многопоточного приложения  
Maluda
1217 / 549 / 104
Регистрация: 18.08.2009
Сообщений: 783
Завершенные тесты: 1
27.02.2013, 19:12 #11
Пишет, что метакласс TPopupMenu не найден. Странно, потому что обращений по метаклассу вроде никаких в коде нет. Возможно особенности каких-то предыдущих версий билдера. может включение какое-то нужно.
Решение такое: бросить вручную на форму TPopupMenu и посмотреть, какие ещё добавятся файлы в заголовочном формы. Или вообще отказаться от динамического создания.
П.С. А вообще рекомендую перейти на более новую версию Билдера.
0
27.02.2013, 19:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.02.2013, 19:12
Привет! Вот еще темы с решениями:

Может, кто-нибудь привести пример простого приложения на фреймворке Slim или Laravel? PHP
Я просто сама не могу разобраться и написать своё что-то

Нужны исходники простого простого приложения под Android для примера
можете дать ссылку на приложение под андроид?не Hello Word а какое нибудь...

Быстродействие многопоточного приложения
Здравствуйте. Я работаю сисадмином и по совместительству неплохо знаю C++ ( не...

Отладка многопоточного приложения
Читаю РИхтера, пытаюсь выполнить его примеры, хотелось бы зайти в отладчик и...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru