Russian Qt Forum
Ноябрь 22, 2024, 22:13 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Выполнение метода класса в новом потоке.  (Прочитано 15837 раз)
rudolfninja
Гость
« : Апрель 09, 2014, 16:07 »

Доброго времени суток. Вопрос может показаться простым\глупым\странным (нужное подчеркнуть), но я, прочитав несколько статей по поводу QThread, так и не совсем понял ответ на него.
Ситуация такая: есть главный поток - UI, у него есть объект класса cpu. В cpu настраиваются регистры, флаги, вбивается программа в память и потом она выполняется. Так вот, надо сделать, чтоб она (программа из памяти cpu) выполнялась в отдельном потоке, чтоб была возможность работать с UI (на случай, если в cpu программа с бесконечным циклом). При этом при все, при завершении выполнения программы из cpu, объект cpu не должен уничтожаться. Он должен ждать пока в него введут новую программу и запустят.
Так вот вопрос в чем: достаточно ли для этого будет просто унаследовать класс cpu от QThread и метод run() перегрузить таким образом, чтоб в нем выполнялась программа, введенная в память процессора? При завершении программы (из памяти процессора) просто убивается процесс ее выполнения, а при повторном запуске программы он снова должен создаваться.
Спасибо.
Записан
OKTA
Гость
« Ответ #1 : Апрель 09, 2014, 16:17 »

Можно, но так делать не рекомендуется и это крайне неудобно, если помимо простого выполнения код в созданном потоке должен обмениваться данными с другими объектами в других потоках. Проще сделать класс-обертку, в котором будет создаваться QThread и ваш cpu. Cpu при этом перемещается в созданный поток через movetothread и через класс-обертку с помощью сигналов обеспечиваются нужные взаимодействия. Я бы делал так  Улыбающийся
Записан
rudolfninja
Гость
« Ответ #2 : Апрель 09, 2014, 16:27 »

если помимо простого выполнения код в созданном потоке должен обмениваться данными с другими объектами в других потоках.
Сам cpu не обязательно кидать в новый поток, он может быть в одном потоке с UI, а вот метод execute() у cpu должен работать в новом потоке. В этом методе будут читаться данные из регистров и памяти cpu, и записываться данные в регистры и память. Получается, что все манипуляции с данными (на время выполнения программы из памяти cpu) будут выполняться в пределах объекта cpu. Хотя программа в память будет вводится из потока с UI.

Проще сделать класс-обертку, в котором будет создаваться QThread и ваш cpu. Cpu при этом перемещается в созданный поток через movetothread и через класс-обертку с помощью сигналов обеспечиваются нужные взаимодействия. Я бы делал так  Улыбающийся

А можно какой-нибудь простенький пример этого приема?
Записан
OKTA
Гость
« Ответ #3 : Апрель 09, 2014, 16:30 »

Если просто метод, то почитайте вот это  Улыбающийся http://qt-project.org/doc/qt-4.8/qtconcurrentrun.html
Записан
rudolfninja
Гость
« Ответ #4 : Апрель 09, 2014, 16:42 »

Насколько я понял, чтоб использовать QtConcurrentRun, то у меня этот метод класса должен быть статическим?
А если использовать метод, который вы предложили ранее, то UI и cpu будут обмениваться данными через эту обертку, так?
Записан
OKTA
Гость
« Ответ #5 : Апрель 09, 2014, 16:43 »

Насколько я понял, чтоб использовать QtConcurrentRun, то у меня этот метод класса должен быть статическим?
А если использовать метод, который вы предложили ранее, то UI и cpu будут обмениваться данными через эту обертку, так?

Да нет, не должен он быть статическим. С чего вы взяли?
Да, через обертку.
Записан
rudolfninja
Гость
« Ответ #6 : Апрель 09, 2014, 16:49 »

Ну, чтоб знать адрес функции на момент компиляции. По крайней мере, Win32Api функции CreateThread надо передавать статический метод класса.
Нашел на форуме тему с моей проблемой: http://www.prog.org.ru/topic_19310_0.html. Буду пробовать сделать таким же образом. Спасибо за помощь.
Записан
rudolfninja
Гость
« Ответ #7 : Апрель 09, 2014, 17:48 »

Сделал так. В UI вбиваю программу, которая будет в cpu выполняться в бесконечном цикле
Код:
void MainWindow::on_start_cx_button_clicked()
{
    _cpu.write_byte_to_memory(CS, 0x100, 0xBA);
    _cpu.write_byte_to_memory(CS, 0x101, 0xFB);
    _cpu.write_byte_to_memory(CS, 0x102, 0xFF);
    _cpu.write_byte_to_memory(CS, 0x103, 0xEC);
    _cpu.write_byte_to_memory(CS, 0x104, 0xBA);
    _cpu.write_byte_to_memory(CS, 0x105, 0xFA);
    _cpu.write_byte_to_memory(CS, 0x106, 0xFF);
    _cpu.write_byte_to_memory(CS, 0x107, 0xEE);
    _cpu.write_byte_to_memory(CS, 0x108, 0xEB);
    _cpu.write_byte_to_memory(CS, 0x109, 0xF6);
    _cpu._registers[IP] = 0x100;
    _cpu._stop_address = 0x10A;

    _cpu.run();
}

В cpu:
Код:
void intel8086::run()
{

    QtConcurrent::run(this, &intel8086::execute);
}

void intel8086::execute()
{
    while(_registers[IP] <= _stop_address){
        step();
    }
}

Однако программа зависает и падает на функции void intel8086::run(). Не подскажете, в чем может быть ошибка?
Тут run выполняет бесконечный цикл и программа валится как только первая итерация проходит.
« Последнее редактирование: Апрель 09, 2014, 17:55 от rudolfninja » Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #8 : Апрель 09, 2014, 18:15 »

А что в step() происходит?
Записан

Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #9 : Апрель 09, 2014, 18:26 »

Если посмотреть на код из on_start_cx_button_clicked, то наверное все таки так:
Код
C++ (Qt)
void intel8086::execute()
{
   while(_registers[IP] < _stop_address){
       step();
   }
}
 
Записан
rudolfninja
Гость
« Ответ #10 : Апрель 09, 2014, 18:52 »

А что в step() происходит?
Step - очень большая и сложная функция. По сути, моя программа - эмулятор микропроцессора. В нее вводится машинный код ассемблеровских команд и cpu их выполняет. В функции степ происходит расшифровка кода команды, определяются операнды и команда и выполняется команда в соответствии с полученным кодом.

Если посмотреть на код из on_start_cx_button_clicked, то наверное все таки так:
Код
C++ (Qt)
void intel8086::execute()
{
   while(_registers[IP] < _stop_address){
       step();
   }
}
 

Вряд ли. Я просто в этом методе ввел команду в память процессора. Потом она будет вводится по другому, это я сейчас для теста так сделал.
Причем в консольном приложении эта программа (вбитая в cpu) отлично отрабатывает в бесконечном цикле.
« Последнее редактирование: Апрель 09, 2014, 18:57 от rudolfninja » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #11 : Апрель 09, 2014, 18:58 »

Я не говорю, что это причина падения. Я просто уточнил, что при указанных вами исходных данных по адресу 0x10A уже не будет кода, а step будет вызван.
Записан
rudolfninja
Гость
« Ответ #12 : Апрель 09, 2014, 19:01 »

Согласен, исправил. Спасибо. Но, к сожалению, это не решение проблемы.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Апрель 09, 2014, 19:05 »

Но, к сожалению, это не решение проблемы.
Скажите, я правильно понимаю, что так все будет работать в одном потоке?
Код
C++ (Qt)
void intel8086::run()
{
   execute();
}
 
void intel8086::execute()
{
   while(_registers[IP] <= _stop_address){
       step();
   }
}
Записан
rudolfninja
Гость
« Ответ #14 : Апрель 09, 2014, 19:08 »

Да. В однопоточном консольном приложении это все отлично отрабатывает.
Ребят, понял в чем проблема. Проблема во взаимодействии с UI. Буду сейчас смотреть где проблема.
Пока что вопрос есть, а как убить выполнение этой функции?
« Последнее редактирование: Апрель 09, 2014, 19:16 от rudolfninja » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.106 секунд. Запросов: 22.