Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.67
el_gato_de_Ch
35 / 35 / 1
Регистрация: 28.04.2013
Сообщений: 110
03.06.2014, 23:06     Многопоточность, выход из бесконечного цикла c++11 #1
Всем привет. Я в задачах многопоточности - новичок (начал ей заниматься буквально несколько часов назад), инфу искал, читал, но как-то пока не помогает.

Столкнулся с задачей (с++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.
Вопрос: Как завершить цикл ?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.06.2014, 23:06     Многопоточность, выход из бесконечного цикла c++11
Посмотрите здесь:

C++ Выход из бесконечного цикла по нажатию кнопки.
Выход из цикла C++
не работает проверка бесконечного цикла C++
Выход из цикла C++
Выход из цикла C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 00:52     Многопоточность, выход из бесконечного цикла c++11 #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");
}
el_gato_de_Ch
35 / 35 / 1
Регистрация: 28.04.2013
Сообщений: 110
04.06.2014, 08:33  [ТС]     Многопоточность, выход из бесконечного цикла c++11 #3
у меня ошибка в оригинальном посте

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

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

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

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

join() как я понимаю блокирует вызывающий поток до завершения функции,
detach() отсоединяет вызванный поток от вызывающего, правильно ?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 12:38     Многопоточность, выход из бесконечного цикла c++11 #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;
      }
   }
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
04.06.2014, 12:40     Многопоточность, выход из бесконечного цикла c++11 #7
Думаю, так как _stopCycle в цикле нигде не изменяется, условие в while оптимизиуется до true. Надо заменить bool на std::atomic<bool> (а не volatile bool, кстати).
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 12:57     Многопоточность, выход из бесконечного цикла c++11 #8
Цитата Сообщение от Somebody Посмотреть сообщение
а не volatile bool, кстати
volatile чем не устраивает?
В первом моём коде (где пауза делается в основном потоке) зацикливания нет (даже без volatile), если убрать паузу, то есть. Вывод?

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

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

Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
if(cmd == exit)
* * * {
* * * * *obj.stop();
* * * * *break;
* * * }
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
04.06.2014, 13:07     Многопоточность, выход из бесконечного цикла c++11 #11
Такое использование volatile не соответствует стандарту.
http://alenacpp.blogspot.ru/2006/04/volatile.html
(И на форуме уже где-то об этом писалось.)
Сейчас уже и M$ это не рекомендует.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 13:15     Многопоточность, выход из бесконечного цикла c++11 #12
Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
да
А заход в while(), где этот if?

Не по теме:

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

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

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

taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
04.06.2014, 13:20     Многопоточность, выход из бесконечного цикла c++11 #13
Была у меня как то проблема межпоточного взаимодействия, выглядело поведение проги так, как если бы два потока работали с отдельными копиями переменных. Может в этом дело?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 13:23     Многопоточность, выход из бесконечного цикла c++11 #14
Цитата Сообщение от taras atavin Посмотреть сообщение
Может в этом дело?
Я думаю, что в этом:
Цитата Сообщение от alsav22 Посмотреть сообщение
У вас крутится потому, что obj.stop() (в главном потоке) происходит раньше, чем _stopCycle = false во втором потоке.
Если, конечно, есть заход в while() в главном потоке (иначе obj.stop() вообще не происходит).
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
04.06.2014, 13:24     Многопоточность, выход из бесконечного цикла c++11 #15
Цитата Сообщение от alsav22 Посмотреть сообщение
В первом моём коде (где пауза делается в основном потоке) зацикливания нет (даже без volatile), если убрать паузу, то есть. Вывод?
Вывод: правильность кода не является необходимым условием для правильности его работы, не более того.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 13:32     Многопоточность, выход из бесконечного цикла c++11 #16
Цитата Сообщение от Somebody Посмотреть сообщение
Вывод: правильность кода не является необходимым условием для правильности его работы, не более того.
Что можете сказать о зацикливании без паузы в основном потоке? Почему происходит?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
04.06.2014, 13:46     Многопоточность, выход из бесконечного цикла c++11 #17
Цитата Сообщение от Somebody Посмотреть сообщение
правильность кода не является необходимым условием для правильности его работы, не более того.
То есть чётная ошибка ошибкой не является?
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
04.06.2014, 14:00     Многопоточность, выход из бесконечного цикла c++11 #18
Цитата Сообщение от alsav22 Посмотреть сообщение
Что можете сказать о зацикливании без паузы в основном потоке? Почему происходит?
В каком коде? Зацикливания в основном потоке не вижу нигде...
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 16:01     Многопоточность, выход из бесконечного цикла c++11 #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;
      }
   }
Когда произойдёт зацикливание во втором потоке, нажмите на любую клавишу.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.06.2014, 18:38     Многопоточность, выход из бесконечного цикла c++11
Еще ссылки по теме:

Выход из бесконечного цыкла C++
Отладка бесконечного цикла C++
C++ Способы остановки бесконечного while цикла

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

Или воспользуйтесь поиском по форуму:
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
04.06.2014, 18:38     Многопоточность, выход из бесконечного цикла c++11 #20
Цитата Сообщение от alsav22 Посмотреть сообщение
Что можете сказать о зацикливании без паузы в основном потоке? Почему происходит?
Действительно, obj.stop() может выполниться раньше, чем _stopCycle = false. При первом запуске у меня этого не произошло, и я не обратил внимания. Но зацикливается не всегда, а как повезёт (у меня, например, с включенным антивирусом зацикливается реже, чем с выключенным). (Однако всего предыдущего про оптимизацию условия и volatile это не отменяет.)
Yandex
Объявления
04.06.2014, 18:38     Многопоточность, выход из бесконечного цикла c++11
Ответ Создать тему
Опции темы

Текущее время: 00:56. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru