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

Работа с потоком в C++Builder

22.04.2015, 23:37. Показов 3663. Ответов 29
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Разработал приложение, которое делает очень много вычислений, процесс отобразил с помощью ProgressBar. В ходе выполнения программа зависала(не отвечала), а через некоторое время выдавала сообщение, что расчеты завершены(заканчивала свою работу правильно). Нашел на форуме решение - проводить все вычисления в отдельном потоке. Так-как с потоками я не работал, я быстро отыскал как его создать и примитивные функции для работы с ним. Проблема в том, что когда я не использовал поток, программа считала быстрее. В чем проблема?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.04.2015, 23:37
Ответы с готовыми решениями:

При работе с файлами и потоком fstream builder не хочет компилировать код
При работе с файлами (код содержит запись и считывание с файла ofstream\ifstream) builder выдает ошибку типа: E2075 Incorrect...

Работа с большим потоком бит
Исследую файл в битовом виде. Ищу совпадение комбинаций внутри потока. Размер блока для исследования - от 2 до 4096. Т.е. например, 100...

Работа с ComboBox в С++ Builder 6
Есть такая проблема, надо на форме связать два ComboBox компонента. При выборе элемента из списка на ComboBox1 ему соответствовал элемент...

29
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,647
Записей в блоге: 6
23.04.2015, 08:25
А еще есть специальные правила:
 Комментарий модератора 
п. 4. 7 Как можно более полно описывайте суть проблемы или вопроса, что было сделано для ее решения и какие результаты получены.
1
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
23.04.2015, 08:26
Цитата Сообщение от Ilot Посмотреть сообщение
Как можно более полно описывайте суть проблемы или вопроса, что было сделано для ее решения и какие результаты получены.
Код в студию, короче.
0
 Аватар для demon_7
260 / 192 / 60
Регистрация: 12.05.2013
Сообщений: 857
23.04.2015, 08:42
Цитата Сообщение от 6Houk9 Посмотреть сообщение
В чем проблема?

Не по теме:

Очевидно же, что в фазе луны после солнечного затмения! Ведь большая медведица отклонилась от млечного пути на 4 дельты.


Без Вашего кода, Вам тут врядли кто поможет, всех экстрасенсов забрали на реалити шоу =(
1
0 / 0 / 0
Регистрация: 22.04.2015
Сообщений: 19
23.04.2015, 11:10  [ТС]
Вод код который прописан в потоке:

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
//---------------------------------------------------------------------------
 
#include <System.hpp>
#pragma hdrstop
 
#include "Unit1.h"
#include "Unit18.h"
#include "stdio.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 MyThread::MyThread(bool CreateSuspended)
    : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall MyThread::Execute()
{
    FILE *FileOut;
    char *NameFile;
    AnsiString StrFile;
 
    StrFile = Form1->Edit1 -> Text;
    NameFile = new char [StrFile.Length() + 1];
    strcpy(NameFile, StrFile.c_str());
    FileOut = fopen(NameFile, "w");
 
    for (j[0] = 0; j[0] < N[0]; j[0]++)
    {
        if (PassLen == 1)
        {
            if (Form1 -> CheckBox1 -> Checked) fprintf(FileOut, "%c\n", Alphabet[0][j[0]]);
            Form1 -> ProgressBar1 -> Position++;
            continue;
        }
        for (j[1] = 0; j[1] < N[1]; j[1]++)
        {
            if (PassLen == 2)
            {
                if (Form1 -> CheckBox1 -> Checked) fprintf(FileOut, "%c%c\n", Alphabet[0][j[0]],\
                Alphabet[1][j[1]]);
                Form1 -> ProgressBar1 -> Position++;
                continue;
            }
......  Еще много циклов for.....
ShowMessage("Расчёт завершен!");
Form1 -> Enabled = true;
fclose(FileOut);
Почему, когда я тот же самый алгоритм прописываю в обычной форме, он работает быстрее?
0
 Аватар для demon_7
260 / 192 / 60
Регистрация: 12.05.2013
Сообщений: 857
23.04.2015, 11:25
Что за написание цикла???
C++
1
2
3
4
5
6
7
8
for (j[0] = 0; j[0] < N[0]; j[0]++)
{
if (PassLen == 1)
{
if (Form1 -> CheckBox1 -> Checked) fprintf(FileOut, "%c\n", Alphabet[0][j[0]]);
Form1 -> ProgressBar1 -> Position++;
continue;
}
Что этот цикл должен делать? это вообще работает?
Где заполняется массив j[] , N[], что такое PassLen?
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
23.04.2015, 11:32
Цитата Сообщение от 6Houk9 Посмотреть сообщение
В чем проблема?
В отсутствии синхронизации.
Ваш поток, заместо того, чтобы самостоятельно обсчитать все, что можно и один раз выдать результат, то и дело лезет в основной (Form1 -> CheckBox1 -> Checked - к примеру). Тут поработал чуть-чуть, пошел в другое место послонялся. И сам короче не работает и другим не дает.
1
0 / 0 / 0
Регистрация: 22.04.2015
Сообщений: 19
23.04.2015, 11:37  [ТС]
Что здесь такого страшного?
В цикле сравнивается переменная PassLen типа int c таким же интом, при истинном значении цикл записывает в файл символ из массива Alphabet[...][...] ( при истинности этого условия конечно: if (Form1 -> CheckBox1 -> Checked)). j[] обрабатывается в управляющей конструкции "for", N[] заполняется в другой форме, массив объявлен как глобальный.

Добавлено через 2 минуты
Как мне тогда быть? Подскажите.) Исключить все обращения в основной поток?)
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
23.04.2015, 11:50
6Houk9, зацените вот эту штуку, которая пишется при создании нового потока:
Цитата Сообщение от 6Houk9 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//---------------------------------------------------------------------------
 
//   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";
//      }
//---------------------------------------------------------------------------
Это специальное предупреждение как раз от того, что вы сделали.

Если в трех словах, то вам нужно код вашего потока разделить на две части: обсчет чего-либо и выдачу результата. В классе потока вы создаете две соответствующие функции. И тогда метод Execute вашего потока будет выглядеть примерно так:
C++
1
2
3
4
5
void __fastcall MyThread::Execute()
{
  Посчитать_всю_хрень_и_сложить_ее_в_соответствующие_переменные_внутри_потока(); // Первая функция
  Synchronize( Поменять_что-то_там_на_форме_на_рассчитанные_значение ); // Вторая функция под синхронизацией
}
0
23.04.2015, 11:57

Не по теме:

Рано ТС потоки изучать, он сишные ф-ции юзает а вы ему VCL, потоки...

0
23.04.2015, 12:00

Не по теме:

Avazart, это как плавать учить, есть методология такая: с лодки бросают в воду и как хочешь. Никаких бассейнов.

0
23.04.2015, 12:04

Не по теме:

Это тогда когда еще тазик нужен и цемент? :D

0
23.04.2015, 12:11

Не по теме:

Avazart, уроки программирования с видом на Гудзонский залив. Х)

0
0 / 0 / 0
Регистрация: 22.04.2015
Сообщений: 19
23.04.2015, 14:11  [ТС]
А как мне быть с ProgressBar -> Position ++? Это необходимо выполнять при каждом шаге каждого цикла.
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
23.04.2015, 14:30
Цитата Сообщение от 6Houk9 Посмотреть сообщение
Это необходимо выполнять при каждом шаге каждого цикла
Нет. Не необходимо.
У вас так индексы в циклах выверены, что инкрементируя позицию прогресса на каждой итерации, ровно в конце цикла он дойдет до ста процентов заполненности?

В любом случае переделывайте логику потока полностью. Полностью. Не суйте костыли.
Вынесите цикл в Execute, и каждые n итераций синхронизируйтесь с прогрессбаром.
0
0 / 0 / 0
Регистрация: 22.04.2015
Сообщений: 19
23.04.2015, 23:56  [ТС]
Да, так выверенно, что доходит до 100% в конце). Спасибо за помощь, уберу все обращения в основной поток, которые находятся в цикле.) А как синхронизировать с ProgressBar на каждом шаге?) Напишите код пожалуйста)

Добавлено через 9 часов 21 минуту
Убрал все обращения к основному потоку из циклов, все равно ему что-то мешает работать быстрей.

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
void __fastcall MyThread::Execute()
{
    FreeOnTerminate = true;
 
    int j[15];
 
    FILE *FileOut;
    char *NameFile;
    AnsiString StrFile;
 
    StrFile = Form1 -> Edit1 -> Text;
    NameFile = new char [StrFile.Length() + 1];
    strcpy(NameFile, StrFile.c_str());
    FileOut = fopen(NameFile, "w");
 
    for (j[0] = 0; j[0] < N[0]; j[0]++)
    {
        if (PassLen == 1)
        {
            if (Flag[0]) fprintf(FileOut, "%c\n", Alphabet[0][j[0]]);
            Synchronize(PrBar);
            continue;
        }
        for (j[1] = 0; j[1] < N[1]; j[1]++)
        {
            if (PassLen == 2)
            {
                if (Flag[0]) fprintf(FileOut, "%c%c\n", Alphabet[0][j[0]],\
                Alphabet[1][j[1]]);
                Synchronize(PrBar);
                continue;
            }
            for (j[2] = 0; j[2] < N[2]; j[2]++)
            {
                if (PassLen == 3)
                {
                    if (Flag[0]) fprintf(FileOut, "%c%c%c\n", Alphabet[0][j[0]],\
                    Alphabet[1][j[1]], Alphabet[2][j[2]]);
                    Synchronize(PrBar);
                    continue;
                }
 
                       .........
    
        ShowMessage("Расчёт завершен!");
    fclose(FileOut);
}
//---------------------------------------------------------------------------
 
void __fastcall MyThread::PrBar()
{
    Form1 -> ProgressBar1 -> Position++;
}
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
24.04.2015, 09:02
Цитата Сообщение от 6Houk9 Посмотреть сообщение
Убрал все обращения к основному потоку из циклов
Вы не убрали их из циклов, вы обернули их в синхронизацию. Это уже хорошо. Но логику потока нужно менять всю, переделывать. Существующая структура тела потока не подходит для вашего задания. Подумайте как ее можно переделать.
Должно получиться что-то типа:
Code
1
2
3
4
5
6
Execute
[
Synchronize( Получить данные с формы )
Рассчитать в циклах что там надо.
Synchronize( Внести изменения на форму )
]
В каноническом ыиде типа вот такого:
Code
1
2
3
4
5
6
7
8
9
Execute
[
Synchronize( Получить данные с формы )
while( ! ThisThread->Terminated )
  [
  Рассчитать в циклах что там надо. 
  Synchronize( Внести изменения на форму )
  ]
]
Применимо к вашему случаю (что не хотелось бы):
Code
1
2
3
4
5
6
7
8
9
Execute
[
Synchronize( Получить данные с формы )
for( Какой-то там цикл, в котором все просчитываем )
  [
  Просчитываем итерацию
  Synchronize( Внести изменения на форму ) // Один раз за цикл
  ]
]
0
0 / 0 / 0
Регистрация: 22.04.2015
Сообщений: 19
24.04.2015, 12:33  [ТС]
Убрал обращения к ProgressBar в цикле, все работает как надо!) Но как тогда отобразит прогресс, раз нельзя обратиться из цикла к основному потоку?
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
24.04.2015, 12:56
6Houk9, заведите переменную, которую внутри цикла увеличивайте. И раз в несколько итераций синхронизируйте значение этой переменной с прогрессбаром на форме.
0
24.04.2015, 13:01

Не по теме:

Да, а еще есть IdNotify ....

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.04.2015, 13:01
Помогаю со студенческими работами здесь

работа с файлами С++ Builder
Куль хацкеры помогите=) решил состряпать прогу для синхронизации файлов с флеш накопителей.. но увы немогу найти каким макаром перемещать,...

Работа с реестром в C++ Builder
Вступление: Данный FAQ тестировался и писался на системе Windows XP SP2. Используемый компилятор: Borland C++ Builder 6.0. ...

С++ Builder и работа с графикой
Доброго времени суток. Возникли вопросы по работе с графикой. Вопрос таков - как создать массив или класс или компоненту, чтобы был...

Работа С++ Builder и Excel
Обрабатываю данные из текстового файла через программу C++ Builder и заношу в таблицу программы Excel. // Всё это в цикле for...

Работа с C++ Builder XE4
Доброго времени суток! Волей случая пришлось запустить одну свою программу. Так как, нормального C++ Borland Duilder в сети не найти, решил...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Команды "Заполнить" и "Очистить" на форме документа
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". На примере нетипового документа разработанного в конфигурации КА2. В качестве источника данных указан регистр накопления, в который записываются данные о. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru