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

Управление потоками

23.11.2012, 18:05. Показов 1362. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток.
с потоками я вроде как разобрался, теперь проблема в их управлении... данная программа реализует два потока, один на канве хаотично рисует прямоугольники, другой треугольники (на них есть две отдельные кнопки).
ПРОБЛЕМА: при нажатии на одну кнопку нужно при помощи HANDLE (Event) и WaitForSingleObject сделать так, что бы сначала рисовался прямоугольник, потом заданное число треугольников, и только потом следующий прямоугольник и т.д. В идеале треугольники должны вырисовываться в четырёхугольнике, но это я уже их сам туда впихну. Мне главное понять управление потоками. Буду признателен за любую помощь.

Главный Юнит .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
#include <vcl.h>
#pragma hdrstop
 
#include "MainPrimitives.h"
#include "ThrRectangle.h"
#include "ThrTriangle.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFPrimitives *FPrimitives;
ThreadRectangle *ThrRec;
ThreadTriangle *ThrTrng;
//---------------------------------------------------------------------------
__fastcall TFPrimitives::TFPrimitives(TComponent* Owner)
        : TForm(Owner)
{
   ThrRec=NULL;
   ThrTrng=NULL;
}
//---------------------------------------------------------------------------
void __fastcall TFPrimitives::BCloseClick(TObject *Sender)
{
  Close();
}
//---------------------------------------------------------------------------
void __fastcall TFPrimitives::BRectangleClick(TObject *Sender)
{
 
        if(ThrRec)
        {
                ThrRec->Terminate();
                delete ThrRec;
                ThrRec=NULL;
        }
        ThrRec = new ThreadRectangle(false);
 
        
}
//---------------------------------------------------------------------------
 
 
void __fastcall TFPrimitives::BStopClick(TObject *Sender)
{
     if(ThrRec)
        {
        ThrRec->Terminate();
        delete ThrRec;
        ThrRec=NULL;
        ThrTrng->Terminate();
        delete ThrTrng;
        ThrTrng=NULL;
        }
}
//---------------------------------------------------------------------------
 
void __fastcall TFPrimitives::BClearClick(TObject *Sender)
{
        Refresh();
}
//---------------------------------------------------------------------------
 
 
void __fastcall TFPrimitives::FormResize(TObject *Sender)
{
    Rct.Left=20;
    Rct.Top=20;
    Rct.Right=ClientWidth-Rct.Left*2;
    Rct.Bottom=ClientHeight-Rct.Top*2-(ClientHeight-Panel1->Top);
}
//---------------------------------------------------------------------------
 
void __fastcall TFPrimitives::BTriangleClick(TObject *Sender)
{
if(ThrTrng)
        {
                ThrTrng->Terminate();
                delete ThrTrng;
                ThrTrng=NULL;
        }
        ThrTrng = new ThreadTriangle(false);        
}
.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
#ifndef MainPrimitivesH
#define MainPrimitivesH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TFPrimitives : public TForm
{
__published:    // IDE-managed Components
        TPanel *Panel1;
        TButton *BClose;
        TButton *BRectangle;
        TButton *BTriangle;
        TButton *BStop;
        TButton *BClear;
        void __fastcall BCloseClick(TObject *Sender);
        void __fastcall BRectangleClick(TObject *Sender);
        void __fastcall BStopClick(TObject *Sender);
        void __fastcall BClearClick(TObject *Sender);
        void __fastcall FormResize(TObject *Sender);
        void __fastcall BTriangleClick(TObject *Sender);
 
private:    // User declarations
public:     // User declarations
        TRect Rct;
        
        __fastcall TFPrimitives(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TFPrimitives *FPrimitives;
//---------------------------------------------------------------------------
#endif
Поток Четырёхугольников .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
#include <vcl.h>
#include <stdlib.h>
#pragma hdrstop
 
#include "ThrRectangle.h"
#include "MainPrimitives.h"
#pragma package(smart_init)
 
//---------------------------------------------------------------------------
 
__fastcall ThreadRectangle::ThreadRectangle(bool CreateSuspended)
        : TThread(CreateSuspended)
{
        randomize();
        StepDoneEvent=CreateEvent(NULL, false, false, NULL);
}
//---------------------------------------------------------------------------
 
__fastcall ThreadRectangle::~ThreadRectangle()
{
        CloseHandle(StepDoneEvent);
}
 
void __fastcall ThreadRectangle::BRectangle()
{
    SetEvent(StepDoneEvent);
    FPrimitives->Canvas->Pen->Width=5;
    FPrimitives->Canvas->Pen->Color=random(0xFFFFFF);
    FPrimitives->Canvas->Brush->Style=bsClear;
    FPrimitives->Canvas->Rectangle(FPrimitives->Rct.Left+random(FPrimitives->Rct.Width()),
                                   FPrimitives->Rct.Top+random(FPrimitives->Rct.Height()),
                                   FPrimitives->Rct.Left+random(FPrimitives->Rct.Width()),
                                   FPrimitives->Rct.Top+random(FPrimitives->Rct.Height()));
    ResetEvent(StepDoneEvent);
}
 
 
void __fastcall ThreadRectangle::Execute()
{
       while (!Terminated)
       {
          try
          {
            Synchronize(BRectangle);
            Sleep(1000);
          }
          catch(Exception &e) {}
       }
}
.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef ThrRectangleH
#define ThrRectangleH
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
class ThreadRectangle : public TThread
{
private:
        void __fastcall BRectangle();
protected:
        void __fastcall Execute();
public:
        HANDLE StepDoneEvent;
        __fastcall ThreadRectangle(bool CreateSuspended);
        __fastcall ~ThreadRectangle();
};
//---------------------------------------------------------------------------
#endif
Поток Трeугольников .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
#include <vcl.h>
#include <winbase.h>
#pragma hdrstop
 
#include "ThrTriangle.h"
#include "MainPrimitives.h"
#include "ThrRectangle.h"
#pragma package(smart_init)
extern ThreadRectangle *ThrRec;
 
//---------------------------------------------------------------------------
 
__fastcall ThreadTriangle::ThreadTriangle(bool CreateSuspended)
        : TThread(CreateSuspended)
{
        randomize();
}
//---------------------------------------------------------------------------
void __fastcall ThreadTriangle::BTriangle()
{
        FPrimitives->Canvas->Pen->Width = 2;
        FPrimitives->Canvas->Pen->Color = random(0xFFFFFF);
        FPrimitives->Canvas->Brush->Style = bsClear;
        TPoint p[3];
        p[0]=Point(random(FPrimitives->Rct.Width()), random(FPrimitives->Rct.Height()));
        p[1]=Point(random(FPrimitives->Rct.Width()), random(FPrimitives->Rct.Height()));
        p[2]=Point(random(FPrimitives->Rct.Width()), random(FPrimitives->Rct.Height()));
        FPrimitives->Canvas->Polygon(p,2);
 
}
 
 
void __fastcall ThreadTriangle::Execute()
{
        while (!Terminated)
                {
                        if(ThrRec && WaitForSingleObject(ThrRec->StepDoneEvent, 20)==WAIT_OBJECT_0)
                        Synchronize(BTriangle);
                        //ThreadTriangle=new ThreadTriangle(this, false);
                        Sleep(400);
                }
}
.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef ThrTriangleH
#define ThrTriangleH
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
class ThreadTriangle : public TThread
{
private:
        void __fastcall BTriangle();
protected:
        void __fastcall Execute();
public:
        __fastcall ThreadTriangle(bool CreateSuspended);
};
//---------------------------------------------------------------------------
#endif
Код работает, но не так как хотелось бы... (написано в 5-ом Билдере)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.11.2012, 18:05
Ответы с готовыми решениями:

Реализовать алгоритм работы планировщика. Управление виртуальной памятью. Управление файловой системой
Разработка программы менеджера памяти. Свопинг. Сегментная схема организации памяти. Управление...

Работе с потоками
Есть вот такой код void __fastcall TForm1::Button2Click(TObject *Sender) { checked=good=0;...

Ошибки с потоками
Пытаюсь сделать многопоточное приложение которое просто загружает страницу (в дальнейшем что нибудь...

Работа с потоками
Всем здравствуйте. Программа обращается к некоторому файлу по локальной сети на удалённом...

4
872 / 448 / 35
Регистрация: 25.10.2011
Сообщений: 910
23.11.2012, 19:30 2
WaitForSingleObject - поможет, только если нужно выполнить второй поток, после завершения первого.
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
//----------------------
HANDLE Thread0 = NULL;
HANDLE Thread1 = NULL;
//----------------------
DWORD __stdcall Method0(void * Source)
{
    TCanvas * Canvas = (TCanvas*)Source;
    
    Canvas->Brush->Color = clGreen;
    for (int index = 0; index < 10; index++)
    {
        int pointx = random(300);
        int pointy = random(300);
        int sizex = random(100);
        int sizey = random(100);
        
        Canvas->Rectangle(pointx,pointy,pointx+sizex,pointy+sizey);
        Sleep(500);
    }
    return NULL;
}
//----------------------
DWORD __stdcall Method1(void * Source)
{
    TCanvas * Canvas = (TCanvas*)Source;
    if (Thread0)
    {
        WaitForSingleObject(Thread0, INFINITE);
        CloseHandle(Thread0);
    }
    
    Canvas->Brush->Color = clRed;
    Canvas->Font->Color = clWhite;
    Canvas->TextOutA(10,10,"Первый поток завершен!");
    
    CloseHandle(Thread1);
    return NULL;
}
//----------------------
void __fastcall TForm::ButtonClick(TObject*)
{
    Thread0 = CreateThread(NULL, NULL, Method0, Canvas, NULL, NULL);
    Thread1 = CreateThread(NULL, NULL, Method1, Canvas, NULL, NULL);
}
//----------------------
Если потоки работают, до тех пор "пока солнце не сядет", то можно делать все "по учебнику" или просто объявить булевую переменную и использовать ее в качестве переключателя (а если задание не требует 2 потока, то можно и вовсе решить все в один поток).
1
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.11.2012, 19:48 3
Если рисование идет через Synchronyze(), а грамостких вычислений нет, то тут не нужны потоки....

Добавлено через 3 минуты
Цитата Сообщение от SlavBuch Посмотреть сообщение
с потоками я вроде как разобрался,
Так что нифига походу не разобрался.

Добавлено через 9 минут
Для блокировки канвы кстати ( без Synchronize) можно использовать
C++
1
2
Image1->Canvas->Lock();
Image1->Canvas->UnLock();
0
129 / 112 / 39
Регистрация: 27.09.2012
Сообщений: 305
23.11.2012, 21:29 4
Цитата Сообщение от Avazart Посмотреть сообщение
Если рисование идет через Synchronyze(), а грамостких вычислений нет, то тут не нужны потоки....
А вместо слипов в отдельном потоке тогда использовать таймеры в основном потоке? Или как вообще реализовывать, чтобы форма не зависала на время рисования?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.11.2012, 22:21 5
Цитата Сообщение от Antiplayer Посмотреть сообщение
А вместо слипов в отдельном потоке тогда использовать таймеры в основном потоке? Или как вообще реализовывать, чтобы форма не зависала на время рисования?
Можно и таймер ну или отдельный поток с низким приоритетом... но явное не плодить потоки.

Во время рисование форма все рано буде зависать так как ресурс -форма...

Добавлено через 21 минуту
Поэтому надо между операциями рисования давать окну возможность обработать другие сообщения.
1
23.11.2012, 22:21
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.11.2012, 22:21
Помогаю со студенческими работами здесь

Работа с потоками
Доброго времени суток. Нужно создать программу, в которой имеется как минимум 3 потока ( форма + 2...

Потоками делать
Есть такая задача, хочу определиться со структурой проги: имеется прибор, по которому через ком...

Работа с потоками
Всем доброго времени суток. Кто может подсказать, как реализовать, вот такую функцию по выяснению...

Разобраться с потоками
Всем добрый день. Встала необходимость разработать приложение с использованием потоков. Почитал как...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru