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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.67
el_gato_de_Ch
35 / 35 / 1
Регистрация: 28.04.2013
Сообщений: 110
#1

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

03.06.2014, 23:06. Просмотров 2136. Ответов 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
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Многопоточность, выход из бесконечного цикла c++11 (C++):

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

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

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

не работает проверка бесконечного цикла - C++
// разработать класс Student, который содержит соответствующие поля для хранения: // * фамилии,+ // * имени,+ // * отчества,+ // *...

Способы остановки бесконечного while цикла - C++
У меня такой вопрос: вот например у нас есть бесконечный цикл while с условиями while(true) { if(..){...} else(...){...}///и так...

Выход из цикла - C++
Есть цикл. Он выполняется. Долго. Пока он выполняется я нажимаю Esc и он становится на паузу. Как осуществить? Добавлено через 10...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Psilon
Master of Orion
Эксперт .NET
5891 / 4788 / 634
Регистрация: 10.07.2011
Сообщений: 14,406
Записей в блоге: 5
Завершенные тесты: 4
05.06.2014, 14:00 #31
Цитата Сообщение от alsav22 Посмотреть сообщение
И где, здесь в теме, такое было?
Цитата Сообщение от taras atavin Посмотреть сообщение
bool по идее однобитный, что уже гарантирует синхронизацию и исключает необходимость мьютексов
далее
Этот код, к вопросу темы, какое отношение имеет?
Проблема: someThread не останавливает работу функции infinite. Цикл так и продолжает крутиться, выполняются do things и show window.
Вопрос: Как завершить цикл ?
0
Somebody
2789 / 1603 / 145
Регистрация: 03.12.2007
Сообщений: 4,193
Завершенные тесты: 1
05.06.2014, 14:06 #32
Цитата Сообщение от alsav22 Посмотреть сообщение
Значит, в этом отношении, ошибки применения нет? Насколько я понимаю, volatile и std::atomic это из разных областей, и для разного применяются.
В этом отношении ошибки нет. Но volatile изначально был введён для работы с отображёнными на память устройствами ввода-вывода. C++98 ничего не говорил о многопоточности, так что volatile был лучше, чем ничего; к тому же MS в своих компиляторах наделил его дополнительным смыслом (acquire/release semantics), которого нет в стандарте. В C++11 решили ничего нового для volatile не придумывать, и просто добавили atomic типы.
Цитата Сообщение от alsav22 Посмотреть сообщение
Понятно, что volatile не решает вопрос синхронизации. Но при чём здесь то, что volatile нужно заменить на atomic, как пишет Somebody? volatile для одного (для чего я его и использовал), atomic для другого. Весь вопрос сводится к тому: является ли тип bool атомарным или не является.
atomic также решает и вопросы синхронизации, и в зависимости от платформы реализация может быть от простых чтения/записи до использования мьютексов.
0
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.06.2014, 14:12 #33
Цитата Сообщение от Psilon Посмотреть сообщение
И где, здесь в теме, такое было?
Сообщение от taras atavin bool по идее однобитный, что уже гарантирует синхронизацию и исключает необходимость мьютексов
Где здесь про то, что volatile синхронизирует?
Цитата Сообщение от Psilon Посмотреть сообщение
volatile отвечает только за отсутствие кэширования значения переменной, за его использование как средства синхронизации со ссылкой на стандарты и пр следует отрывать руки.
Цитата Сообщение от Psilon Посмотреть сообщение
далее
И...? Где в вашем коде, вообще, второй поток? Как проверять будет зацикливание или нет? Этот код про то, как избежать зацикливания? Или про что?

Добавлено через 5 минут
Цитата Сообщение от Somebody Посмотреть сообщение
atomic также решает и вопросы синхронизации,
С этим никто не спорит. Но можно использовать volatile, и мьютексы для синхронизации, т.е., не заменять, в моём коде, volatile на atomic, а добавить мьютексы. Как вариант?
0
Psilon
Master of Orion
Эксперт .NET
5891 / 4788 / 634
Регистрация: 10.07.2011
Сообщений: 14,406
Записей в блоге: 5
Завершенные тесты: 4
05.06.2014, 14:22 #34
Цитата Сообщение от alsav22 Посмотреть сообщение
Где здесь про то, что volatile синхронизирует?
исключает необходимость мьютексов
необходимость мьютексов
мьютексов
Цитата Сообщение от alsav22 Посмотреть сообщение
И...? Где в вашем коде, вообще, второй поток? Как проверять будет зацикливание или нет? Этот код про то, как избежать зацикливания? Или про что?
главный поток - первый, создаваемый - второй. Для иллюстрации вполне достаточно. Этот код про то, что код зацикливался из-за неправильной синхронизации, а в этом коде порядок операций фиксирован.
0
Somebody
2789 / 1603 / 145
Регистрация: 03.12.2007
Сообщений: 4,193
Завершенные тесты: 1
05.06.2014, 14:22 #35
Раз тут пошёл виндовый код: в таком случае можно LONG вместо bool и InterlockedCompareExchange.
Цитата Сообщение от alsav22 Посмотреть сообщение
С этим никто не спорит. Но можно использовать volatile, и мьютексы для синхронизации, т.е., не заменять, в моём коде, volatile на atomic, а добавить мьютексы. Как вариант?
Да.
1
Psilon
Master of Orion
Эксперт .NET
5891 / 4788 / 634
Регистрация: 10.07.2011
Сообщений: 14,406
Записей в блоге: 5
Завершенные тесты: 4
05.06.2014, 14:23 #36
Somebody, да, про interlocked не подумал Хорошая мысль.
0
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.06.2014, 14:31 #37
Цитата Сообщение от Psilon Посмотреть сообщение
исключает необходимость мьютексов
bool и volatile, по-вашему, это одинаковые слова?
Цитата Сообщение от Psilon Посмотреть сообщение
главный поток - первый, создаваемый - второй.
Где они в вашем коде?
Цитата Сообщение от Psilon Посмотреть сообщение
Этот код про то, что код зацикливался из-за неправильной синхронизации,
Код зацикливается совсем по другой причине (так же как и ваш, если не добавить паузу перед циклом в основном потоке).

Добавлено через 2 минуты
Узнаёте ваш класс? Зацикливает.
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <thread>
#include <mutex>
#include <cstdlib>
#include <Windows.h>
using namespace std;
 
 
class SomeClass
{
    CRITICAL_SECTION gCS;
    volatile bool _stopCycle;
public:
    SomeClass()
    {
        InitializeCriticalSection(&gCS);
    }
 
    ~SomeClass()
    {
        DeleteCriticalSection(&gCS);
    }
 
    void inifiniteWhile()   {
        if (_stopCycle)
        {
            EnterCriticalSection(&gCS);
            _stopCycle = false;
            LeaveCriticalSection(&gCS);
        }
        while (!_stopCycle)
        {
            cout << "inifiniteWhile" << endl;
        }
    }
 
    void stop() {
        if (!_stopCycle)
        {
            EnterCriticalSection(&gCS);
            _stopCycle = true;
            LeaveCriticalSection(&gCS);
        }
    }
};
 
int main(int argv, char* argc[])
{
    SomeClass obj;
    thread someThread(&SomeClass::inifiniteWhile, &obj);
    someThread.detach();
 
    while(true)
    {
        if(true)
        {
            obj.stop();
            break;
        }
    }
 
    system("pause");
    
    return 0;
}
0
Psilon
Master of Orion
Эксперт .NET
5891 / 4788 / 634
Регистрация: 10.07.2011
Сообщений: 14,406
Записей в блоге: 5
Завершенные тесты: 4
05.06.2014, 14:59 #38
alsav22, что зацикливает? 1 раз отрабатывает сообщение, после этого остановка, все как и положено.
0
Миниатюры
Многопоточность, выход из бесконечного цикла c++11  
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.06.2014, 15:03 #39
По-вашему, я придумываю? Вот здесь почитайте: Многопоточность, выход из бесконечного цикла c++11
0
Миниатюры
Многопоточность, выход из бесконечного цикла c++11  
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.06.2014, 15:17 #40
Неправильность этого кода в том, что нет ничего, чтобы гарантировало выполнение функции inifiniteWhile() во втором потоке раньше, чем вызов функции stop() в основном потоке.
Вот здесь, во втором коде, такая гарантия сделана: Многопоточность, выход из бесконечного цикла c++11
1
Psilon
Master of Orion
Эксперт .NET
5891 / 4788 / 634
Регистрация: 10.07.2011
Сообщений: 14,406
Записей в блоге: 5
Завершенные тесты: 4
05.06.2014, 15:27 #41
alsav22, если вызывающему коду нужно вставлять задержки для корректной работы, то это хрень, а не многопоточное приложение.

Не вижу беды в том, что Stop() будет вызван раньше, чем начнется поток - он и не обязан вызываться позже.
0
taras atavin
Ушёл с форума.
3569 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.06.2014, 15:28 #42
Поищите ка, где я хоть что то утверждаю про volatile.
0
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.06.2014, 15:41 #43
Цитата Сообщение от Psilon Посмотреть сообщение
если вызывающему коду нужно вставлять задержки для корректной работы, то это хрень, а не многопоточное приложение.
Согласен, для этого я выложил второй код, без задержки. Задержка - это чтобы обозначить причину зацикливания.
Цитата Сообщение от Psilon Посмотреть сообщение
Не вижу беды в том, что Stop() будет вызван раньше, чем начнется поток
Если stop() будет вызвана рашьше, то _stopCycle = true и выход из цикла в основном потоке, затем (если позже) следует заход в inifiniteWhile(), _stopCycle = false и заход в цикл, выход из которого возможен только если _stopCycle = true. Поздравляю с зацикливанием!

Добавлено через 5 минут
Я вам скрин выложил, как у меня работает (это когда stop() вызывается раньше). Всё равно: "не вижу беды"?
0
taras atavin
Ушёл с форума.
3569 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.06.2014, 15:49 #44
Цитата Сообщение от alsav22 Посмотреть сообщение
Если stop() будет вызвана рашьше, то _stopCycle = true и выход из цикла в основном потоке, затем (если позже) следует заход в inifiniteWhile(), _stopCycle = false и заход в цикл, выход из которого возможен только если _stopCycle = true. Поздравляю с зацикливанием!
stop() должна присваивать значение, гарантирующее выход из цикла, а будучи вызванной до запуска потока, эта же функция должна присваивать тоже самое значение, но уже гарантировано предотвращающее старт цикла. Если же stop() присваивает значение, исключающее выход из цикла, то её вызов ни при каких условиях не приведёт к остановке потока, не зависимо от того, вызвана ли она после старта цикла, или же до. Не уподобляйтесь мелкомягким: не нарушайте логику приложения.
0
alsav22
5420 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.06.2014, 15:55 #45
taras atavin, вот код - 37 пост, вот зацикливание - скрин в 39 посте. Почему зацикливание, по-вашему, происходит?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.06.2014, 15:55
Привет! Вот еще темы с ответами:

Выход из цикла - C++
Ув. программисты я пишу крестики-нолики, но возникла некоторая проблема с циклами! for (t=0;t&lt;100;t++) { for...

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

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

Принудительный выход из цикла - C++
Вообщем надо при определенном условии завершать вложенный цикл, такой код будет работать??? for(.....) { for(.....) { if...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
05.06.2014, 15:55
Ответ Создать тему
Опции темы

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