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

Потоки, TThread, нет синхронизации

06.12.2012, 17:38. Показов 1836. Ответов 18

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

Код C++

C++
1
2
3
4
5
6
7
8
void __fastcall TForm1::Button2Click(TObject *Sender) {
 
    p_thread->StopWork();
    while (run)
        Sleep(100);
    StatusBar1->Panels->Items[0]->Text = "Статус: отдых";
 
}

Программка подвисает при нажатии Button2.

Полный текст класса потока:

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
//---------------------------------------------------------------------------
 
 
#include <vcl.h>
#pragma hdrstop
 
#include "TMyThread.h"
#include "parser.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 MyThread::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//
//
//---------------------------------------------------------------------------
 
 
__fastcall TMyThread::TMyThread(bool CreateSuspended) : TThread(CreateSuspended) {
 
    inquiryRun = 0;
    FreeOnTerminate = true;
 
}
 
 
//---------------------------------------------------------------------------
 
 
void __fastcall TMyThread::ReadInterface(void) {
 
    //
 
}
 
 
//---------------------------------------------------------------------------
 
 
void __fastcall TMyThread::WriteInterface(void) {
 
    Form1->Caption = ("Работает поток " + IntToStr(i));
    Form1->Refresh();
 
}
 
 
//---------------------------------------------------------------------------
 
 
void __fastcall TMyThread::WorkControler(void) {
 
    if (inquiryRun == -1)
        Form1->run = false;
    else if (inquiryRun == 1)
        Form1->run = true;
    inquiryRun = 0;
 
}
 
 
//---------------------------------------------------------------------------
 
 
void __fastcall TMyThread::Execute() {
 
    i = 0;
    while (!Terminated) {
        if (Form1->run) {
            Synchronize(ReadInterface);
            Sleep(500);
            Synchronize(WriteInterface);
            ++i;
        }
        else
            Sleep(100);
        WorkControler();
    }
 
}
 
 
//---------------------------------------------------------------------------
 
 
void TMyThread::StartWork(void) {
 
    inquiryRun = 1;
 
}
 
 
//---------------------------------------------------------------------------
 
 
void TMyThread::StopWork(void) {
 
    inquiryRun = -1;
 
}
 
 
//---------------------------------------------------------------------------
 
 
bool TMyThread::GetRun(void) {
 
    return Form1->run;
 
}
 
 
//---------------------------------------------------------------------------

переменная run - объявлена в классе Form1, а меняется в потоке, поэтому я в цикле жду, когда поток её поменяет, чтобы можно было окончить "Стоп".
Проблема в подвисании программы в функции Button2Click. Как правильно организовать взаимодействие, не подскажите, чтобы не подвисала и всё работало?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
06.12.2012, 17:38
Ответы с готовыми решениями:

Потоки(TThread)
Здраствуйте. У меня возникла следующая проблема, начал изучать потоки,когда создаю три потока, третий должен запуститься после окочания...

Алгоритмы синхронизации TThread и VCL
Здравствуйте форумчане. Подскажите алгоритмы синхронизации потока с формой. А может методы другие. Суть вопроса. Как синхронизировать...

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

18
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
06.12.2012, 19:07
Могу ошибаться, но Sleep усыпляет все и потки тоже.
А вы хотите убить поток или приостановить его?
0
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 178
06.12.2012, 19:17  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall TForm1::Button2Click(TObject *Sender) {
 
    p_thread->StopWork();
 
        // Тут я жду типа
    while (run)
          Sleep(100);
 
    StatusBar1->Panels->Items[0]->Text = "Статус: отдых";
 
}
Мне нужно просто подождать, пока поток окончит рабочую операцию и перейдёт на холостой ход. Sleep тормозит только поток, в котором вызвана.
0
60 / 57 / 8
Регистрация: 22.07.2011
Сообщений: 436
06.12.2012, 19:37
Sleep() приостанавливает выполнение текущего потока, а не всех.
0
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 178
06.12.2012, 21:32  [ТС]
Решение нашёл, используя критическую секцию. Думаю, кому-то будет полезно:

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
// Form1
 
void __fastcall TForm1::Button2Click(TObject *Sender) {
 
    if (run) {
        run = false;
        EnterCriticalSection(&stop);
        LeaveCriticalSection(&stop);
        StatusBar1->Panels->Items[0]->Text = "Статус: отдых";
    }
 
}
 
 
// Поток
 
//---------------------------------------------------------------------------
 
 
void __fastcall TMyThread::ReadInterface(void) {
 
    //
 
}
 
 
//---------------------------------------------------------------------------
 
 
void __fastcall TMyThread::WriteInterface(void) {
 
    Form1->Caption = ("Работает поток " + IntToStr(i));
    Form1->Refresh();
 
}
 
 
//---------------------------------------------------------------------------
 
 
void __fastcall TMyThread::Execute() {
 
    i = 0;
    while (!Terminated) {
        if (Form1->run)
            Synchronize(ReadInterface);
 
        EnterCriticalSection(&Form1->stop);
        if (Form1->run) {
            Sleep(500); // Тут рабочие операции
            ++i;
        }
        LeaveCriticalSection(&Form1->stop);
 
        if (Form1->run)
            Synchronize(WriteInterface);
        else
            Sleep(50);
    }
 
}
 
 
//---------------------------------------------------------------------------
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
07.12.2012, 03:50
В первом варианте были тормоза скорее всего т.к. вы использовали Synchronize, т.е. Synchronize ждал спящий основной поток.
В последнем варианте:
1. Плохо что поток использует внешнюю переменную Form1->run, по идее все переменные нужные для работы класса должны быть в нем самом.
2. Вариант с критическими секциями не пройдет когда нужно запускать несколько таких потоков, но наверно это не ваш случай.
Помнится когда я делал подобное я еще использовал WaitForSingleObject и ResetEvent
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.12.2012, 04:11
C++
1
if (Form1->run)
Собственно вместо переменной run и нужно использовать критическую секцию...
Обращаться к переменной сразу из двух потоков опасно.

Лучше использовать объект vcl TCriticalSection пример есть в справке среды...
0
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 178
07.12.2012, 16:37  [ТС]
Привет! С учётом замечаний и предложений коллег по цеху C++, выкладываю пару классов, где ранее описанная задачка решена более корректно:

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
class TForm1 : public TForm, public IInterfaceToTMyThread {
 
    __published:
 
        TButton *Button1;
        TButton *Button2;
        TStatusBar *StatusBar1;
        TMemo *Memo1;
 
....................
 
//---------------------------------------------------------------------------
 
 
void __fastcall TForm1::ReadInterface(void) {
 
    //
 
}
 
 
//---------------------------------------------------------------------------
 
 
void __fastcall TForm1::WriteInterface(void) {
 
    Caption = ("Работает поток " + IntToStr(i));
    Refresh();
    ++i;
 
}
 
 
//---------------------------------------------------------------------------
 
 
void TForm1::Work(void) {
 
    Sleep(200);
 
}
 
 
//---------------------------------------------------------------------------
 
 
bool TForm1::GetRun(void) {
 
    return run;
 
}
 
 
//---------------------------------------------------------------------------
 
 
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
 
    i = 0;
    run = false;
 
    p_ini = new TIniFile(GetCurrentDir() + "\\config.ini");
    ReadHostIni();
    ReadMySqlIni();
 
    p_parserVideo = new TParserVideo(L"localhost", 60000, delay);
    p_thread = new TMyThread(false);
    p_thread->SetWorkingParameters(this);
 
}
 
 
//---------------------------------------------------------------------------
 
 
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) {
 
    WriteHostIni();
    WriteMySqlIni();
    Button4Click(Sender);
 
    if (p_parserVideo)
        delete p_parserVideo;
 
    if (p_ini)
        delete p_ini;
 
    if (p_thread) {
        p_thread->Suspend();
        p_thread->UnsetWorkingParameters();
        p_thread->Terminate();
    }
 
}
 
 
//---------------------------------------------------------------------------
 
 
void __fastcall TForm1::Button1Click(TObject *Sender) {
 
    if (!run)
        if (WriteHost()) {
            StatusBar1->Panels->Items[0]->Text = "Статус: работа";
            p_parserVideo->setSleep(delay);
            run = true;
            Sleep(50);
        }
 
}
 
 
//---------------------------------------------------------------------------
 
 
void __fastcall TForm1::Button2Click(TObject *Sender) {
 
    if (run) {
        run = false;
        p_thread->WorkEnd();
        Sleep(50);
        StatusBar1->Panels->Items[0]->Text = "Статус: отдых";
    }
 
}
 
 
//---------------------------------------------------------------------------
Добавлено через 2 минуты
Интерфейс к потоку

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
//---------------------------------------------------------------------------
 
 
#ifndef IInterfaceToTMyThreadH
#define IInterfaceToTMyThreadH
 
 
//---------------------------------------------------------------------------
 
 
class IInterfaceToTMyThread {
 
    public:
 
        virtual void __fastcall ReadInterface(void) = 0;
        virtual void __fastcall WriteInterface(void) = 0;
        virtual void Work(void) = 0;
        virtual bool GetRun(void) = 0;
 
 
};
 
 
//---------------------------------------------------------------------------
 
 
#endif
Добавлено через 2 минуты
Класс потока с хидером:

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
//---------------------------------------------------------------------------
 
 
#ifndef TMyThreadH
#define TMyThreadH
 
 
//---------------------------------------------------------------------------
 
 
#include <Classes.hpp>
#include <mylib/IInterfaceToTMyThread/IInterfaceToTMyThread.h>
 
 
//---------------------------------------------------------------------------
 
 
typedef void __fastcall FuncForSynchr(void);
typedef void __fastcall FuncWork(void);
 
 
class TMyThread : public TThread {
 
    private:
 
        IInterfaceToTMyThread* p_object;
        TCriticalSection *p_criticalSection;
 
    protected:
 
        void __fastcall Execute();
 
    public:
 
        __fastcall TMyThread(bool CreateSuspended);
        void SetWorkingParameters(IInterfaceToTMyThread* p_object_p);
        void UnsetWorkingParameters(void);
        bool WorkEnd(void);
 
};
 
 
//---------------------------------------------------------------------------
 
 
#endif
 
// ---------------------------------------------------------------------------
 
 
#include <vcl.h>
#pragma hdrstop
 
#include "TMyThread.h"
#pragma package(smart_init)
 
 
// ---------------------------------------------------------------------------
 
 
__fastcall TMyThread::TMyThread(bool CreateSuspended) : TThread(CreateSuspended) {
 
    p_object = 0;
    FreeOnTerminate = true;
 
}
 
 
// ---------------------------------------------------------------------------
 
 
void TMyThread::SetWorkingParameters(IInterfaceToTMyThread* p_object_p) {
 
    p_criticalSection = new TCriticalSection();
    p_object = p_object_p;
 
}
 
 
// ---------------------------------------------------------------------------
 
 
void TMyThread::UnsetWorkingParameters(void) {
 
    p_criticalSection->Enter();
    p_object = 0;
    p_criticalSection->Release();
    delete p_criticalSection;
    p_criticalSection = 0;
 
}
 
 
// ---------------------------------------------------------------------------
 
 
bool TMyThread::WorkEnd(void) {
 
    if (p_criticalSection) {
        p_criticalSection->Enter();
        p_criticalSection->Release();
    }
    return true;
 
}
 
 
// ---------------------------------------------------------------------------
 
 
void __fastcall TMyThread::Execute() {
 
    while (!Terminated) {
        if (p_object && p_criticalSection) {
            if (p_object->GetRun()) {
                Synchronize(p_object->ReadInterface);
                p_criticalSection->Enter();
                p_object->Work();
                p_criticalSection->Release();
                Synchronize(p_object->WriteInterface);
            }
            else
                Sleep(50);
        }
        else
            Sleep(50);
    }
 
}
 
 
// ---------------------------------------------------------------------------
Добавлено через 3 минуты
Класс потока полностью независимый, можно использовать его с интерфейсом IInterfaceToTMyThread. Функция WorkEnd ждёт и сигнализирует об окончании рабочей операции.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.12.2012, 17:14
C++
1
2
3
p_criticalSection->Enter();
                p_object->Work();
p_criticalSection->Release();
А исключения ловить кто будет ?
Собственно нафига я справку Builder указал ?
0
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 178
07.12.2012, 17:31  [ТС]
Да нет в баркадере справки, а онлайн кривая совсем. Есть нормальная справка, где можно качнуть?

Добавлено через 2 минуты
Avazart, предлагаешь обрамить цикл потока блоком try?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.12.2012, 17:36
Если будет исключение, то твоя крит.секция останется на веке заЛочена...

Добавлено через 1 минуту
Цитата Сообщение от Юрий Ч Посмотреть сообщение
Да нет в баркадере справки, а онлайн кривая совсем. Есть нормальная справка, где можно качнуть?
Это у же ваши проблемы ... у меня нормально работает как встроенная так и с сайта.
0
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 178
07.12.2012, 17:37  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void __fastcall TMyThread::Execute() {
 
    while (!Terminated) {
        try {
            if (p_object && p_criticalSection) {
                if (p_object->GetRun()) {
                    Synchronize(p_object->ReadInterface);
                    p_criticalSection->Enter();
                    p_object->Work();
                    p_criticalSection->Release();
                    Synchronize(p_object->WriteInterface);
                }
                else
                    Sleep(50);
            }
            else
                Sleep(50);
        } catch (...) {
            p_object->ErrorProcessing();
        }
    }
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.12.2012, 17:40
Кажется так

C++
1
2
3
4
5
6
7
8
p_criticalSection->Enter();
try{ 
      p_object->Work(); 
    }
__finally
 { 
   p_criticalSection->Release(); 
 }
0
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 178
07.12.2012, 17:42  [ТС]
В ErrorProcessing() надо бы пихнуть всю доступную инфу об ошибке. Наверное, типа так:

C++
1
2
3
        } catch (Exception exp) {
            p_object->ErrorProcessing(exp);
        }
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.12.2012, 17:44
Надо кому то почитать книги... или хотя бы статью как обрабатывать исключения и синхронизацию потоков.
0
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 178
07.12.2012, 17:58  [ТС]
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
// ---------------------------------------------------------------------------
 
 
void __fastcall TMyThread::Execute() {
 
    while (!Terminated) {
        try {
            if (p_object && p_criticalSection) {
                if (p_object->GetRun()) {
                    Synchronize(p_object->ReadInterface);
                    p_criticalSection->Enter();
 
                    try {
                        p_object->Work();
                    }
                    catch (Exception exp) {
                        p_object->ErrorProcessing(exp);
                    }
                    __finally {
                        p_criticalSection->Release();
                    }
 
                    Synchronize(p_object->WriteInterface);
                }
                else
                    Sleep(50);
            }
            else
                Sleep(50);
        } catch (Exception exp) {
            p_object->ErrorProcessing(exp);
        }
    }
 
}
 
 
// ---------------------------------------------------------------------------
Добавлено через 2 минуты
Avazart, книги для умников, и не факт, что решения, которые там приводятся лучше тех, что придумываем мы сами.

Добавлено через 1 минуту
На то она и голова, чтобы думать.

Добавлено через 6 минут
Avazart, лихой класс получился с вашей помощью. Ещё чуток подшаманить и будет совсем хорошо.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.12.2012, 18:08
Цитата Сообщение от Юрий Ч Посмотреть сообщение
Avazart, книги для умников, и не факт, что решения, которые там приводятся лучше тех, что придумываем мы сами.
Факт ...
Цитата Сообщение от Юрий Ч Посмотреть сообщение
На то она и голова, чтобы думать
Нужно ее еще иметь...

В общем по вашей логике- думайте зачем моя помощь и помощь форума... это для умников ...
думайте ...на то и голова..
0
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 178
07.12.2012, 23:07  [ТС]
Avazart, Тут я бы послал кого-то куда подальше или ещё дальше, но не сделаю этого, так как, возможно, придётся ещё раз что-то спросить. Но я постараюсь больше не спрашивать по возможности и обходиться своими силами. ) А впереди окончательное описание класса, разработанного мной и Avazart.

Добавлено через 1 минуту
Avazart, Поберегу Вашу голову от глупых вопросов.

Добавлено через 2 минуты
Avazart, На счёт книг, остаюсь при своём мнении. В первую очередь нужно думать самому, потом уже пользоваться готовыми решениями. За исключением классики языка, естественно (Шилдт, Страуструпп).

Добавлено через 4 часа 40 минут
Ну и окончательное пока решение для класса потока.

Интерфейс

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 IInterfaceToTMyThreadH
#define IInterfaceToTMyThreadH
 
 
//---------------------------------------------------------------------------
 
 
class IInterfaceToTMyThread {
 
    public:
 
        virtual void __fastcall ReadInterface(void) = 0;
        virtual void __fastcall WriteInterface(void) = 0;
        virtual void Work(void) = 0;
        virtual bool GetRun(void) = 0;
        virtual bool ErrorProcessing(Exception *p_e_p) = 0;
 
 
};
 
 
//---------------------------------------------------------------------------
 
 
#endif
Класс потока:

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
//---------------------------------------------------------------------------
 
 
#ifndef TMyThreadH
#define TMyThreadH
 
 
//---------------------------------------------------------------------------
 
 
#include <Classes.hpp>
#include <SysUtils.hpp>
#include <mylib/IInterfaceToTMyThread/IInterfaceToTMyThread.h>
 
 
//---------------------------------------------------------------------------
 
 
class TMyThread : public TThread {
 
    private:
 
        IInterfaceToTMyThread* p_object;
        TCriticalSection *p_criticalSection;
 
    protected:
 
        void __fastcall Execute();
 
    public:
 
        __fastcall TMyThread(bool CreateSuspended);
        void SetWorkingParameters(IInterfaceToTMyThread* p_object_p);
        void UnsetWorkingParameters(void);
        bool WorkEnd(void);
 
};
 
 
//---------------------------------------------------------------------------
 
 
#endif
 
 
 
// ---------------------------------------------------------------------------
 
 
#include <vcl.h>
#pragma hdrstop
 
#include "TMyThread.h"
#pragma package(smart_init)
 
 
// ---------------------------------------------------------------------------
 
 
__fastcall TMyThread::TMyThread(bool CreateSuspended) : TThread(CreateSuspended) {
 
    p_object = 0;
    FreeOnTerminate = true;
 
}
 
 
// ---------------------------------------------------------------------------
 
 
void TMyThread::SetWorkingParameters(IInterfaceToTMyThread* p_object_p) {
 
    p_criticalSection = new TCriticalSection();
    p_object = p_object_p;
 
}
 
 
// ---------------------------------------------------------------------------
 
 
void TMyThread::UnsetWorkingParameters(void) {
 
    p_criticalSection->Enter();
    p_object = 0;
    p_criticalSection->Release();
    delete p_criticalSection;
    p_criticalSection = 0;
 
}
 
 
// ---------------------------------------------------------------------------
 
 
bool TMyThread::WorkEnd(void) {
 
    if (p_criticalSection) {
        p_criticalSection->Enter();
        p_criticalSection->Release();
    }
    return true;
 
}
 
 
// ---------------------------------------------------------------------------
 
 
void __fastcall TMyThread::Execute() {
 
    while (!Terminated) {
        try {
            if (p_object && p_criticalSection) {
                if (p_object->GetRun()) {
                    Synchronize(p_object->ReadInterface);
                    p_criticalSection->Enter();
 
                    try {
                        try {
                            p_object->Work();
                        } catch (Exception *e) {
                            p_object->ErrorProcessing(e);
                        }
                    }
                    __finally {
                        p_criticalSection->Release();
                    }
 
                    Synchronize(p_object->WriteInterface);
                }
                else
                    Sleep(50);
            }
            else
                Sleep(50);
        } catch (Exception *e) {
            p_object->ErrorProcessing(e);
        }
    }
 
}
 
 
// ---------------------------------------------------------------------------
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.12.2012, 00:58
Еще десятка другого try/catчев не хватает , а то можно было на этом велосипеде к индусам ездить...


C++
1
2
3
4
5
6
7
8
_fastcall TMyThread::TMyThread(bool CreateSuspended) : TThread(CreateSuspended)
 {
 p_object = 0; FreeOnTerminate = true; 
} 
// --------------------------------------------------------------------------- 
void TMyThread::SetWorkingParameters(IInterfaceToTMyThread* p_object_p) 
{ 
p_criticalSection = new TCriticalSection();
Тут та и проблема что секция должна жить вместе с ресурсом, а не погибать с потоком.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.12.2012, 00:58
Помогаю со студенческими работами здесь

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

Потоки и объект синхронизации семафор
Доброго времени суток. Есть задача: Напишите программу, использующую семафор для ограничения количества запущенных потоков, работающих в...

Нет синхронизации Проводника и рабочего стола
Здравствуйте. Прошу помощи Ребят, сразу скажу что я не слишком круто шарю в компах... поэтому собственно и обратился к вам. В общем...

УТ 3.1 д/Украины. Обмен с сайтом. При синхронизации не выгружаются цены и остатки по складам, нет файла offers
Все товары выгружаются, кроме наличия и цен. Когда я в разделе &quot;Узел обмена с сайтом&quot; выбираю &quot;Цены по соглашениям и остатки...

Windows Server 2003: Dropbox, при попытке подключения к интернету для синхронизации пишет, что нет соединенияи
Доброго времени суток,уважаемые форумчане! Прошу помощи в разрешении проблемы. Имеется компьютер с ОС Win 2003 Server на...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Очистка реквизитов документа при копировании
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
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru