Vasara Posted January 17, 2021 Share Posted January 17, 2021 (edited) Добрый день! Странная проблема с инициализацией потоков. В отладчике, с заходом в инициализацию переменной объектов, потоки запускаются и отрабатывают без проблем. Если код запустить без прохода отладчиком, выполняется только один объект в основном потоке. Не понимаю что могло пойти не так. if (Input::isKeyUp(Input::KEY_B)) { MyThread th3; MyThread th4; th3.run(); th4.run(); th3.setValue(0); th4.setValue(9); th3.stop(); th4.stop(); } #pragma once #include <UnigineThread.h> using namespace Unigine; class MyThread : public Thread { public: MyThread(); ~MyThread(); void setValue(int value); int getValue() const; private: int a = 0; mutable Mutex lock; void process() override; }; #include "MyThread.h" MyThread::MyThread() { } MyThread::~MyThread() { } void MyThread::setValue(int value) { //ScopedLock atomic(lock); a = value; } int MyThread::getValue() const { //ScopedLock atomic(lock); return a; } void MyThread::process() { for (size_t i = 0; i < 5; i++) { a++; //lock.lock(); Log::message("ID = %d\n", getID()); Log::message("VAL = %d\n", a); Log::message("\n......................\n"); //lock.unlock(); sleep(2000); } } С Уважением, Константин! thread_test.zip Edited January 18, 2021 by Vasara Link to comment
cash-metall Posted January 18, 2021 Share Posted January 18, 2021 Добрый день. run не запускает поток незамедлительно, он лишь сообщает ОС, что можно запустить поток. ОС сама запустит поток как только будет возможность. для решения этой проблемы можно добавить метод waitRunning class MyThread : public Thread { public: MyThread(); ~MyThread(); void setValue(int value); int getValue() const; private: int a = 0; mutable Mutex lock; mutable Mutex lock_running; // additional mutex void process() override; }; #include "MyThread.h" MyThread::MyThread() { lock_running.lock(); // lock this mutex in constructor } MyThread::~MyThread() { } void MyThread::setValue(int value) { //ScopedLock atomic(lock); a = value; } int MyThread::getValue() const { //ScopedLock atomic(lock); return a; } void waitRunning() const { lock_running.lock(); // wait for lock_running will be unlocked } void MyThread::process() { lock_running.unlock() // and unlock when thread is realy started for (size_t i = 0; i < 5; i++) { a++; //lock.lock(); Log::message("ID = %d\n", getID()); Log::message("VAL = %d\n", a); Log::message("\n......................\n"); //lock.unlock(); sleep(2000); } } вы можете вызывать этот метод как самостоятельно MyThread th3; MyThread th4; th3.run(); th4.run(); th4.waitRunning(); th3.waitRunning(); // wait real running th3.setValue(0); th4.setValue(9); th3.stop(); th4.stop(); так и добавить его внутрь метода run virtual int MyThread::run(size_t size = 0x100000) override { Thread::run(size); waitRunning(); } Это зависит от того, какое поведение вы ожидаете. иначе stop успевает вызываться до того, как поток вообще был запущен - поэтому у вас разное поведение при остановке отладчиком - при остановке потоки успевают нормально запустится. этот баг(или не баг?) пофишкен в 2.14. мы добавили проверку при остановке потока. Link to comment
Vasara Posted January 18, 2021 Author Share Posted January 18, 2021 2 hours ago, cash-metall said: run не запускает поток незамедлительно, он лишь сообщает ОС, что можно запустить поток. Спасибо, картинка сложилась, почему поведение отличалось от стдшного скрипта. Думаю любой результат работы методов, отличный от заявленного в документации, можно относить к багам. Link to comment
Recommended Posts