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

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

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Приостановить поток  (Прочитано 18899 раз)
qt_user
Гость
« Ответ #15 : Ноябрь 20, 2011, 18:37 »

"многопоточное программирование" только на первый взгляд кажется простым, но это не так  Улыбающийся
так с этим никто и не спорит Улыбающийся
Записан
qt_user
Гость
« Ответ #16 : Ноябрь 20, 2011, 19:50 »

2) Эти операции атомарные, но чтение+запись такой переменной нужно защищать блокировками
хотелось бы еще такое узнать, а если доступ к переменной через ссылку или через указатель:
Код:
1. wState = &workState;
2. *wState = run;
3. if (*wState == stop) {}

2 и 3 также будет атомарно?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #17 : Ноябрь 20, 2011, 23:10 »

2 и 3 также будет атомарно?
Будет-то будет, но код в котором даже все операции атомарны может успешно рухнуть - потому что др нитка может вклиниться между операциями. Простой пример
Код
C++ (Qt)
int a. b;
..
if (a == b)
a = 0;
b = 100;
}  
 
Здесь все атомарно, но тем не менее придется это место защищать блокировкой. Начиная от момента когда выполнилось a == b до момента когда выполнится a = 0 могло произойти многое, др нитка(и) могли изменить  a и b как они хотели.
Цитировать
С Ларисой я действительно пил вино, но это было на пасху
Записан
qt_user
Гость
« Ответ #18 : Ноябрь 20, 2011, 23:14 »

Будет-то будет, но код в котором даже все операции атомарны может успешно рухнуть - потому что др нитка может вклиниться между операциями. Простой пример
Код
C++ (Qt)
int a. b;
..
if (a == b)
a = 0;
b = 100;
}
 
Здесь все атомарно, но тем не менее придется это место защищать блокировкой. Начиная от момента когда выполнилось a == b до момента когда выполнится a = 0 могло произойти многое, др нитка(и) могли изменить  a и b как они хотели.
Пасиба, это мы усвоили Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #19 : Ноябрь 20, 2011, 23:22 »

Пасиба, это мы усвоили Улыбающийся
Ну то так кажется - на эти грабли наступают все и много-много раз  Улыбающийся
Записан
JamS007
Гость
« Ответ #20 : Январь 03, 2012, 23:24 »

1. void QThread::sleep ( unsigned long secs )

лучше эту:
void QThread::yieldCurrentThread () [static]

она более "приближенная к системе", заставит передать управление другому потоку чтобы не тратить такты процессора в холостую.
Записан
qt_user
Гость
« Ответ #21 : Январь 04, 2012, 00:33 »

1. void QThread::sleep ( unsigned long secs )

лучше эту:
void QThread::yieldCurrentThread () [static]

она более "приближенная к системе", заставит передать управление другому потоку чтобы не тратить такты процессора в холостую.
не очень понимаю смысл этой ф-ции.. эта ф-ция просто передает управление другому потоку на один квант времени? то есть
отдает 1 свой квант другому потоку?

В чем тогда разница QThread::yieldCurrentThread () и QThread::sleep("1 квант времени")?
Записан
JamS007
Гость
« Ответ #22 : Январь 04, 2012, 00:49 »

qt_user
yieldCurrentThread() передаст управление другой нити, и тем самым прекратит выполнение первой. Отличие от sleep() состоит в том, что в следующий раз поток будет "разбужен" когда этого захочет планировщик, а не по истечению интервала времени.

из доки:
void QThread::sleep ( unsigned long secs ) [static protected]
Forces the current thread to sleep for secs seconds.

1. Нет никаких гарантий, что функция sleep() приведет к передаче управления другому потоку. Гипотетически - так должно быть, и наверное так часто и есть, но все-же.
2. Вы не сможете указать функции sleep() квант времени меньше 1 секунды, да есть msleep() но там Вы не сможете указать квант времени меньше 1 милисекунды.
3. sleep() только запускает механизм, который будет проверять прошел ли заданный промежуток времени или нет. Ничего не сказано о том, как эта проверка осуществляться. Она может выполниться 1 раз (через указанный промежуток времени) или 10 раз... Соответственно, за каждым разом будут потрачены ресурсы системы на сопоставление текущего времени с намеченным для пробуждения. В Вашем случае можно сэкономить эти затраты, ведь у вас уже есть условие, к которому можно привязаться (блокировка по мьютексу, а не точное время).

Я даже встречал негативные отзывы в сторону boost::thread за функцию sleep(). Там она реализована таким образом, что сопоставляет время системы с запланированным для пробуждения, и если в ОС сменить время, к примеру, на день назад, то поток будет разбужен через день+интервал времени, заданный функции sleep(). Подозреваю, что в Qt также.
« Последнее редактирование: Январь 04, 2012, 01:06 от HaySayCheese » Записан
qt_user
Гость
« Ответ #23 : Январь 04, 2012, 23:13 »

HaySayCheese
Спасибо большое, а то я много слышал что sleep плохо, но не видел да и не понимал как работает yieldCurrentThread()
насчет пункта 2. есть еще QThread::usleep ( unsigned long usecs ) для микросекунд
Записан
BRE
Гость
« Ответ #24 : Январь 04, 2012, 23:24 »

HaySayCheese
Спасибо большое, а то я много слышал что sleep плохо, но не видел да и не понимал как работает yieldCurrentThread()
Ну скорее sleep плохо не потому, что он не передает (или передает) управление другому потоку, а в неэффективности самого ожидания.
Например, поток ожидает какие-то данные и пока их нет засыпает на одну секунду. Данные могут придти в любой момент, т.е. поток проверил и заснул, а в этот момент данные появились, поток все равно будет спать секунду, а только потом проснется и обнаружит данные для обработки, хотя могу бы уже секунду как работать.
Поэтому, лучше использовать специальные механизмы, которые могут пробудить поток в тот момент, когда данные появились, например, условные переменные (QWaitCondition).
Записан
thechicho
Гость
« Ответ #25 : Январь 06, 2012, 17:38 »

я чтобы сделать паузу в потоках, делал как-то так

.h потока
public:
    bool условие;
поток::run()
{
QEventLoop loopPause;

if (условие) {
connect(this, SIGNAL(pause()), &loopPause, SLOT(quit()));
loopPause.exec();
}

}

слот потока::blabla()
{
    emit pause();
}

слот главного потока::клик_на_мышку_пауза()
{
    if(поток->условие) {
        поток->условие = false;
        emit pause();
    } else {
        поток->условие = true;
    }
}

слот главного потока::создаем_потоки()
{
     for (int i = 0; i < 100500; i++) {
         класспотока *поток = new класспотока(this);
         поток->условие = false;
         connect(this, SIGNAL(pause()), поток, SLOT(blabla()));
         поток->погнали!;
     }
}

потом раскидывал
if (условие) {
connect(this, SIGNAL(pause()), &loopPause, SLOT(quit()));
loopPause.exec();

перед затратными по времени операциями и усе.
запускал по 500 потоков, работало все ч0тко.)
« Последнее редактирование: Январь 06, 2012, 17:43 от thechicho » Записан
thechicho
Гость
« Ответ #26 : Январь 06, 2012, 17:52 »

а не чуток по-другому, ща глянул.

при создании потоков
connect(this, SIGNAL(pauseThreadTrueSignal()), thread, SLOT(pauseThreadTrueSlot()));
connect(this, SIGNAL(pauseThreadFalseSignal()), thread, SLOT(pauseThreadFalseSlot()));

connect(ui->pushButtonStart, SIGNAL(clicked()), this, SLOT(pauseSlot()));

void гуи поток::pauseSlot()
{
    if (isIconPlay) {
        emit pauseThreadTrueSignal();
    } else {
        emit pauseThreadFalseSignal();
    }
}



void поток::pauseThreadTrueSlot()
{
    //qDebug() << "pauseThread: true";
    pauseThread = true;
    if (workManual)
        emit labelStatusSignal("Пауза");
}

void поток::pauseThreadFalseSlot()
{
    //qDebug() << "pauseThread: false";
    pauseThread = false;
    emit pauseDisabledSignal();    
    if (workManual)
        emit labelStatusClearSignal();
}

if (pauseThread) {
     connect(this, SIGNAL(pauseDisabledSignal()), &loopPause, SLOT(quit()));
     loopPause.exec();
}

isIconPlay - эт условие в гуи потоке (bool). я картинку делал прост, тип play, pause (еще и stop делал).
короче работало все на ура. я хз, нафик заморачиваться с атомарными операциями, если так проще и работает без проблем. но дело ваше, конечно Улыбающийся
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


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