Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/14: Рейтинг темы: голосов - 14, средняя оценка - 5.00
el_gato_de_Ch
35 / 35 / 2
Регистрация: 28.04.2013
Сообщений: 110
1

Многопоточность, выход из бесконечного цикла c++11

03.06.2014, 23:06. Просмотров 2568. Ответов 70
Метки нет (Все метки)

Всем привет. Я в задачах многопоточности - новичок (начал ей заниматься буквально несколько часов назад), инфу искал, читал, но как-то пока не помогает.

Столкнулся с задачей (с++11 std::thread) код не оригинальный, а упрощённый, чтобы показать саму суть, подразумевается, что все необходимые include'ы уже есть.

есть
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class SomeClass
{
private:
   bool _stopCycle;
public:
  void inifiniteWhile()
  {
      _stopCycle = false;
 
      while(!_stopCycle)
      {
          // do things ...
          // show window
      }
  }
 
   void stop() {_stopCycle = false;}
 
};
Main function

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main()
{
   SomeClass obj;
   thread someThread(&SomeClass::obj, infiniteCycle);
 
   while(/*read command from cmd*/)
   {
      if(cmd == exit)
      {
         obj.stop();
         break;
      }
   }
 
   system("pause");
}
Гарантируется, что из while(read cmd) программа выходит, т.е. я прихожу к system("pause");

Проблема: someThread не останавливает работу функции infinite. Цикл так и продолжает крутиться, выполняются do things и show window.
Вопрос: Как завершить цикл ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.06.2014, 23:06
Ответы с готовыми решениями:

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

Выход из бесконечного цыкла
Проблема с выходом из бесконечного цикла. Если для выхода вводить exit,...

Отладка бесконечного цикла
Здравствуйте. Проблема такая, написал цикл программы взаимодействия...

Способы остановки бесконечного while цикла
У меня такой вопрос: вот например у нас есть бесконечный цикл while с условиями...

Не работает проверка бесконечного цикла
// разработать класс Student, который содержит соответствующие поля для...

70
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 00:52 2
Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
Как завершить цикл ?
Присвоить _stopCycle true.

Добавлено через 37 минут
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
#include <iostream>
#include <thread>
#include <cstdlib>
using namespace std;
 
class SomeClass
{
    volatile bool _stopCycle;
public:
 
  void inifiniteWhile()
  {
      _stopCycle = false;
      while (!_stopCycle)
      {
          cout << "inifiniteWhile" << endl;
      }
  }
 
   void stop() {_stopCycle = true;}
 
};
 
int main()
{
   SomeClass obj;
   thread someThread(&SomeClass::inifiniteWhile, &obj);
   someThread.detach();
 
   chrono::milliseconds dura(10);
   this_thread::sleep_for(dura);
 
   while(true)
   {
      if(true)
      {
         obj.stop();
         break;
      }
   }
 
   system("pause");
}
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
#include <iostream>
#include <thread>
#include <cstdlib>
using namespace std;
 
class SomeClass
{
public:
  volatile bool _stopCycle;
 
  SomeClass()
  {
      _stopCycle = true;
  }
 
  void inifiniteWhile()
  {
      _stopCycle = false;
 
      while(!_stopCycle)
      {
          cout << "inifiniteWhile ";
      }
  }
 
   void stop() {_stopCycle = true;}
 
};
 
int main()
{
   SomeClass obj;
   thread someThread(&SomeClass::inifiniteWhile, &obj);
   someThread.detach();
 
   while(true)
   {
      if(!obj._stopCycle)
      {
         obj.stop();
         break;
      }
   }
 
   system("pause");
}
0
el_gato_de_Ch
35 / 35 / 2
Регистрация: 28.04.2013
Сообщений: 110
04.06.2014, 08:33  [ТС] 3
у меня ошибка в оригинальном посте

C++
1
2
3
4
void SomeClass::stop()
{
   _stopCycle = true;
}
и цикл всё равно крутится =(
0
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 12:19 4
Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
и цикл всё равно крутится =(
Я показал, как можно сделать, чтобы не крутился.

Добавлено через 2 минуты
У вас крутится потому, что obj.stop() (в главном потоке) происходит раньше, чем _stopCycle = false во втором потоке.
0
el_gato_de_Ch
35 / 35 / 2
Регистрация: 28.04.2013
Сообщений: 110
04.06.2014, 12:26  [ТС] 5
alsav22, я сильно сомневаюсь в том что obj.stop() происходит раньше старта, к сожалению, сейчас исходников нет, я проверить не смогу, но я полагаю что работает это так:

1. у меня происходит запуск потока с циклом
2. Основной поток в этот момент начинает считывать команды с консоли
3. stop() вызывается только, когда в консоль придёт соответствующая команда (цикл уже стартовал) ...

читая описание, я не совсем понял как работает detach(), если не трудно объясните попроще,

join() как я понимаю блокирует вызывающий поток до завершения функции,
detach() отсоединяет вызванный поток от вызывающего, правильно ?
0
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 12:38 6
Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
но я полагаю что работает это так:
Полагать можно всё что угодно. Работа вашего кода показывает, что ваши предположения неверны. Сделайте паузу в остновном потоке (как у меня в первом коде), чтобы второй поток успел дойти до _stopCycle = false, тогда можно уже будет рассуждать.
Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
читая описание, я не совсем понял как работает detach(), если не трудно объясните попроще,
Это к вопросу о зацикливании отношения не имеет, читайте документацию.

Добавлено через 2 минуты
Вот этот кусок нормальный выложите, чтобы можно было проверить работу:
C++
1
2
3
4
5
6
7
8
while(/*read command from cmd*/)
   {
      if(cmd == exit)
      {
         obj.stop();
         break;
      }
   }
0
Somebody
2799 / 1610 / 251
Регистрация: 03.12.2007
Сообщений: 4,213
Завершенные тесты: 3
04.06.2014, 12:40 7
Думаю, так как _stopCycle в цикле нигде не изменяется, условие в while оптимизиуется до true. Надо заменить bool на std::atomic<bool> (а не volatile bool, кстати).
0
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 12:57 8
Цитата Сообщение от Somebody Посмотреть сообщение
а не volatile bool, кстати
volatile чем не устраивает?
В первом моём коде (где пауза делается в основном потоке) зацикливания нет (даже без volatile), если убрать паузу, то есть. Вывод?

Добавлено через 1 минуту
Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
у меня ошибка в оригинальном посте
И не одна.

Добавлено через 7 минут
Цитата Сообщение от alsav22 Посмотреть сообщение
Вывод?
Но это всё рассуждения относительно моего кода. У ТС может и другая быть причина (связанная с оптимизацией или с чем другим), но проверить нет возможности из-за непонятного куска кода.
0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
04.06.2014, 13:01 9
Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
у меня ошибка в оригинальном посте
C++
1
2
3
4
void SomeClass::stop()
{
 _stopCycle = true;
}
и цикл всё равно крутится =(
А ты её вызываешь?
0
el_gato_de_Ch
35 / 35 / 2
Регистрация: 28.04.2013
Сообщений: 110
04.06.2014, 13:06  [ТС] 10
taras atavin, да

Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
if(cmd == exit)
* * * {
* * * * *obj.stop();
* * * * *break;
* * * }
0
Somebody
2799 / 1610 / 251
Регистрация: 03.12.2007
Сообщений: 4,213
Завершенные тесты: 3
04.06.2014, 13:07 11
Такое использование volatile не соответствует стандарту.
http://alenacpp.blogspot.ru/2006/04/volatile.html
(И на форуме уже где-то об этом писалось.)
Сейчас уже и M$ это не рекомендует.
0
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 13:15 12
Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
да
А заход в while(), где этот if?

Не по теме:

Добавлено через 3 минуты

Цитата Сообщение от Somebody Посмотреть сообщение
Такое использование volatile не соответствует стандарту.
Не будем отвлекаться и спорить на другую тему (я вообще потоки С++11 не использую (использую Qt)).
Цитата Сообщение от Somebody Посмотреть сообщение
Сейчас уже и M$ это не рекомендует.
Какое отношение M$ имеет к стандарту? Пусть дальше рекомендует...

Добавлено через 3 минуты
...
Цитата Сообщение от alsav22 Посмотреть сообщение
В первом моём коде (где пауза делается в основном потоке) зацикливания нет (даже без volatile), если убрать паузу, то есть. Вывод?

0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
04.06.2014, 13:20 13
Была у меня как то проблема межпоточного взаимодействия, выглядело поведение проги так, как если бы два потока работали с отдельными копиями переменных. Может в этом дело?
0
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 13:23 14
Цитата Сообщение от taras atavin Посмотреть сообщение
Может в этом дело?
Я думаю, что в этом:
Цитата Сообщение от alsav22 Посмотреть сообщение
У вас крутится потому, что obj.stop() (в главном потоке) происходит раньше, чем _stopCycle = false во втором потоке.
Если, конечно, есть заход в while() в главном потоке (иначе obj.stop() вообще не происходит).
0
Somebody
2799 / 1610 / 251
Регистрация: 03.12.2007
Сообщений: 4,213
Завершенные тесты: 3
04.06.2014, 13:24 15
Цитата Сообщение от alsav22 Посмотреть сообщение
В первом моём коде (где пауза делается в основном потоке) зацикливания нет (даже без volatile), если убрать паузу, то есть. Вывод?
Вывод: правильность кода не является необходимым условием для правильности его работы, не более того.
0
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 13:32 16
Цитата Сообщение от Somebody Посмотреть сообщение
Вывод: правильность кода не является необходимым условием для правильности его работы, не более того.
Что можете сказать о зацикливании без паузы в основном потоке? Почему происходит?
0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
04.06.2014, 13:46 17
Цитата Сообщение от Somebody Посмотреть сообщение
правильность кода не является необходимым условием для правильности его работы, не более того.
То есть чётная ошибка ошибкой не является?
0
Somebody
2799 / 1610 / 251
Регистрация: 03.12.2007
Сообщений: 4,213
Завершенные тесты: 3
04.06.2014, 14:00 18
Цитата Сообщение от alsav22 Посмотреть сообщение
Что можете сказать о зацикливании без паузы в основном потоке? Почему происходит?
В каком коде? Зацикливания в основном потоке не вижу нигде...
0
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 16:01 19
Цитата Сообщение от Somebody Посмотреть сообщение
В каком коде?
В моём, первом (если убрать паузу в основном потоке).
Цитата Сообщение от Somebody Посмотреть сообщение
Зацикливания в основном потоке не вижу нигде...
Об этом и речь нигде не идёт...
Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
не останавливает работу функции infinite. Цикл так и продолжает крутиться, выполняются do things и show window.
Во втором потоке.

Добавлено через 1 час 12 минут
el_gato_de_Ch, попробуйте, в своём коде, вот так сделать:
C++
1
2
3
4
5
6
7
8
9
10
   while(/*read command from cmd*/)
   {
      if(cmd == exit)
      {
         cout << "if()" << endl;
         system("pause");
         obj.stop();
         break;
      }
   }
Когда произойдёт зацикливание во втором потоке, нажмите на любую клавишу.
0
Somebody
2799 / 1610 / 251
Регистрация: 03.12.2007
Сообщений: 4,213
Завершенные тесты: 3
04.06.2014, 18:38 20
Цитата Сообщение от alsav22 Посмотреть сообщение
Что можете сказать о зацикливании без паузы в основном потоке? Почему происходит?
Действительно, obj.stop() может выполниться раньше, чем _stopCycle = false. При первом запуске у меня этого не произошло, и я не обратил внимания. Но зацикливается не всегда, а как повезёт (у меня, например, с включенным антивирусом зацикливается реже, чем с выключенным). (Однако всего предыдущего про оптимизацию условия и volatile это не отменяет.)
0
04.06.2014, 18:38
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.06.2014, 18:38

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

С++ Выход из цикла
Есть цикл, написанный в дополнительной функции. Нужно вывести сумму нескольких...

Выход из цикла
Ув. программисты я пишу крестики-нолики, но возникла некоторая проблема с...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru