36 / 36 / 2
Регистрация: 28.04.2013
Сообщений: 110
1

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

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

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

Столкнулся с задачей (с++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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.06.2014, 23:06
Ответы с готовыми решениями:

Выход из бесконечного цикла
Реально ли сделать выход из цикла без команды ввода? Допустим идет бесконечный цикл и в любой...

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

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

Выход из бесконечного цикла
Сегодня как дурачок создаю сотую тему, но все же прошу помощи. Есть программа, которая решает вот...

70
5498 / 4893 / 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
36 / 36 / 2
Регистрация: 28.04.2013
Сообщений: 110
04.06.2014, 08:33  [ТС] 3
у меня ошибка в оригинальном посте

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

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

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

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

join() как я понимаю блокирует вызывающий поток до завершения функции,
detach() отсоединяет вызванный поток от вызывающего, правильно ?
0
5498 / 4893 / 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
2835 / 1644 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
04.06.2014, 12:40 7
Думаю, так как _stopCycle в цикле нигде не изменяется, условие в while оптимизиуется до true. Надо заменить bool на std::atomic<bool> (а не volatile bool, кстати).
0
5498 / 4893 / 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
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.06.2014, 13:01 9
Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
у меня ошибка в оригинальном посте
C++
1
2
3
4
void SomeClass::stop()
{
 _stopCycle = true;
}
и цикл всё равно крутится =(
А ты её вызываешь?
0
36 / 36 / 2
Регистрация: 28.04.2013
Сообщений: 110
04.06.2014, 13:06  [ТС] 10
taras atavin, да

Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
if(cmd == exit)
* * * {
* * * * *obj.stop();
* * * * *break;
* * * }
0
2835 / 1644 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
04.06.2014, 13:07 11
Такое использование volatile не соответствует стандарту.
http://alenacpp.blogspot.ru/2006/04/volatile.html
(И на форуме уже где-то об этом писалось.)
Сейчас уже и M$ это не рекомендует.
0
5498 / 4893 / 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
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.06.2014, 13:20 13
Была у меня как то проблема межпоточного взаимодействия, выглядело поведение проги так, как если бы два потока работали с отдельными копиями переменных. Может в этом дело?
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 13:23 14
Цитата Сообщение от taras atavin Посмотреть сообщение
Может в этом дело?
Я думаю, что в этом:
Цитата Сообщение от alsav22 Посмотреть сообщение
У вас крутится потому, что obj.stop() (в главном потоке) происходит раньше, чем _stopCycle = false во втором потоке.
Если, конечно, есть заход в while() в главном потоке (иначе obj.stop() вообще не происходит).
0
2835 / 1644 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
04.06.2014, 13:24 15
Цитата Сообщение от alsav22 Посмотреть сообщение
В первом моём коде (где пауза делается в основном потоке) зацикливания нет (даже без volatile), если убрать паузу, то есть. Вывод?
Вывод: правильность кода не является необходимым условием для правильности его работы, не более того.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
04.06.2014, 13:32 16
Цитата Сообщение от Somebody Посмотреть сообщение
Вывод: правильность кода не является необходимым условием для правильности его работы, не более того.
Что можете сказать о зацикливании без паузы в основном потоке? Почему происходит?
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.06.2014, 13:46 17
Цитата Сообщение от Somebody Посмотреть сообщение
правильность кода не является необходимым условием для правильности его работы, не более того.
То есть чётная ошибка ошибкой не является?
0
2835 / 1644 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
04.06.2014, 14:00 18
Цитата Сообщение от alsav22 Посмотреть сообщение
Что можете сказать о зацикливании без паузы в основном потоке? Почему происходит?
В каком коде? Зацикливания в основном потоке не вижу нигде...
0
5498 / 4893 / 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
2835 / 1644 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
04.06.2014, 18:38 20
Цитата Сообщение от alsav22 Посмотреть сообщение
Что можете сказать о зацикливании без паузы в основном потоке? Почему происходит?
Действительно, obj.stop() может выполниться раньше, чем _stopCycle = false. При первом запуске у меня этого не произошло, и я не обратил внимания. Но зацикливается не всегда, а как повезёт (у меня, например, с включенным антивирусом зацикливается реже, чем с выключенным). (Однако всего предыдущего про оптимизацию условия и volatile это не отменяет.)
0
04.06.2014, 18:38
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.06.2014, 18:38
Помогаю со студенческими работами здесь

Выход из бесконечного цикла
я начинаю изучать PHP, задача такая: есть бесконечный цикл отправки POST запроса как сделать чтоб ...

Выход из бесконечного цикла
Здравствуйте Посмотрите вот такой интересный код s := 1; i := 1; repeat s := s/2; ...

Выход из бесконечного цикла
Как выйти из этого цикла при условии, что сгенерируется значение FAFZYMA2 while(true) ...

Выход из бесконечного цикла программно
Всем привет! Хочу сделать прогу дни рождения. Так вот вопрос такой подскажите как выходить из...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru