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

C++

Войти
Регистрация
Восстановить пароль
 
 
mat_for_c
128 / 123 / 27
Регистрация: 26.04.2013
Сообщений: 627
Завершенные тесты: 2
#1

Корректно убить поток - C++

21.10.2015, 09:42. Просмотров 710. Ответов 27
Метки нет (Все метки)

Пусть имеется поток thrdWork, который обрабатывает большие данные. В результате этой работы в памяти каждый раз сохраняются наиболее лучшие результаты. Т.к. эти результаты перезаписываются, то вывод их в файл возможен по окончанию обработки данных, что не реально долго (возможно и сутки, если не дольше). Поэтому я хочу выводить результаты по нажатию на клавишу (скажем мне будет достаточно того, что thrdWork уже нашел), но при этом дальнейшая обработка мне не нужна, т.е. поток нужно убить раньше времени. Я пришел к 2 решениям:

1 решение:
Кликните здесь для просмотра всего текста
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
void Work()
{
   thread thrdWork(Processing);
   thrdWork.detach();
 
   char cmd;
 
   while (true) {
      cin >> cmd;
 
      if (cmd == 'd')
         // отладочная информация
         // сколько и с какими параметрами найдены
         writeDebugInfo();                
      else if (cmd == 'p') {
         writeBest();
         return;
      }
   }
}
 
 
//main
   thread thrd(Work);
   thrd.join();


и 2 способ:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// main
 
   vector<thread> v_thrd;
   v_thread.push_back(thread(Processing)); // thrdWork
 
   char cmd;
 
   while (true) {
      cin >> cmd;
 
      if (cmd == 'd')
         // отладочная информация
         // сколько и с какими параметрами найдены
         writeDebugInfo();                
      else if (cmd == 'p') {
         writeBest();
         v_thrd.clear();
      }
   }


Какой метод более корректен или есть решение получше,
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
quwy
Native x86
3083 / 1931 / 510
Регистрация: 13.02.2013
Сообщений: 6,432
27.10.2015, 19:41     Корректно убить поток #21
Цитата Сообщение от Avazart Посмотреть сообщение
Это заведомо глупый совет, освежите знания!
До тех пор, пока мне не приведут реальный сценарий появления проблемы при попытке остановки потоков с использованием volatile bool, я остаюсь при своем.

Добавлено через 2 минуты
Первая ссылка лишь на ваше мнение, а во второй затрагивается вопрос модификации данных несколькими потоками, в то время как в данной теме все несколько иначе: рабочие потоки читают переменную, и только один управляющий поток -- пишет.
Убежденный
Системный программист
Эксперт С++
14890 / 6708 / 1059
Регистрация: 02.05.2013
Сообщений: 11,000
Завершенные тесты: 1
27.10.2015, 21:04     Корректно убить поток #22
Цитата Сообщение от quwy
Только не забудьте объявить ее как volatile.
Цитата Сообщение от Dmitriy_M
То что вы говорите это хаки завязанные на реализацию bool, volatile в конкретных
компиляторах на конкретных архитектурах.
Если речь про Visual C++ и x86/x64, то там как раз есть такие гарантии, часть из них
дает компилятор (Microsoft Specific), часть аппаратура, в итоге иногда можно успешно
обходиться без atomic и ко. В данном конкретном случае (mat_for_c: каждый раз буду
опрашивать переменную, отвечающую за завершение потока) использование volatile корректно.

В худшем случае можно получить ситуацию, описанную quwy выше:

Цитата Сообщение от quwy
ожидающий сигнала поток провернет один лишний цикл вместо того, чтобы завершиться немедленно.
Т.е. из-за эффекта store buffers потоки, выполняющиеся на других процессорах,
могут увидеть новое значение volatile-переменной не сразу, а спустя какое-то
время (например, когда на исходном CPU возникнет прерывание).
Avazart
7044 / 5221 / 259
Регистрация: 10.12.2010
Сообщений: 22,944
Записей в блоге: 17
27.10.2015, 21:08     Корректно убить поток #23
В данном конкретном случае нет смысла думать об архитектуре и гарантиях ибо и так уже используется С++11.
Убежденный
Системный программист
Эксперт С++
14890 / 6708 / 1059
Регистрация: 02.05.2013
Сообщений: 11,000
Завершенные тесты: 1
27.10.2015, 21:13     Корректно убить поток #24
А в C++11 есть средства, по функциональности идентичные поведению volatile в VC++ ?
Avazart
7044 / 5221 / 259
Регистрация: 10.12.2010
Сообщений: 22,944
Записей в блоге: 17
27.10.2015, 21:29     Корректно убить поток #25
std::atomic_flag ?
Убежденный
Системный программист
Эксперт С++
14890 / 6708 / 1059
Регистрация: 02.05.2013
Сообщений: 11,000
Завершенные тесты: 1
27.10.2015, 21:54     Корректно убить поток #26
Вообще-то да, тут ты полностью прав, а я, что называется, заврался.
При условии правильного использования atomic и memory_order можно добиться в
точности того же поведения, как с volatile (при этом большой плюс к переносимости).
Здесь я имею в виду ситуацию, когда, например, нужно несколько раз писать в
переменную, но при этом не вызывать сброс кэшей до нужного момента: volatile в
паре с MemoryBarrier (в VC++) обеспечивает такое поведение по умолчанию, а
для atomic нужно в явном виде указывать флаги типа memory_order_relaxed и в
финале memory_order_seq_cst.
nmcf
4758 / 4096 / 1367
Регистрация: 14.04.2014
Сообщений: 16,085
27.10.2015, 22:55     Корректно убить поток #27
Дядьки серьёзные такие сложные вещи начали обсуждать, что я уже перестаю понимать.
А разве memory_order_relaxed к Intel процессорам применим? Там же вроде бы никакого relaxed и не бывает, процессор сам синхронизирует выполнение.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.10.2015, 09:57     Корректно убить поток
Еще ссылки по теме:

Скопировать поток и добавить ошибки в поток C++
C++ Скопировать поток в поток
Как убить процесс? C++
Разработать программу, в которой основной поток, принимает поток ввода и контролирует созданные потоки. C++ Linux
C++ WinAPI Убить Windows

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

Или воспользуйтесь поиском по форуму:
Убежденный
Системный программист
Эксперт С++
14890 / 6708 / 1059
Регистрация: 02.05.2013
Сообщений: 11,000
Завершенные тесты: 1
28.10.2015, 09:57     Корректно убить поток #28
Цитата Сообщение от nmcf Посмотреть сообщение
А разве memory_order_relaxed к Intel процессорам применим?
Memory_order определяет семантику доступа к atomic в терминах модели памяти C++,
а не в терминах конкретных архитектур типа Intel, ARM и т.п. Т.е. если я пишу:
C++
1
AtomicVar.store(0x123, std::memory_model_relaxed);
то компилятор должен обеспечить для AtomicVar только атомарность записи 0x123 и все,
ни о возможном переупорядочивании, ни о других побочных эффектах ему заботиться не нужно
(я немного упрощаю, т.к. какие-то дополнительные требования к relaxed все же есть,
знатоки C++11 подскажут). При этом вполне возможно, что процессорная архитектура, на
которой выполняется данный код, вообще свободна от таких побочных эффектов.

Цитата Сообщение от nmcf Посмотреть сообщение
Там же вроде бы никакого relaxed и не бывает, процессор сам синхронизирует выполнение.
Это не совсем так.
На Intel (x86 и x64, про Itanium отдельная история) операции store-load могут выполняться
процессором в обратном порядке. Кроме того, запись в память одним процессором может
некоторое время быть не видна другим процессорам из-за store buffers.
Yandex
Объявления
28.10.2015, 09:57     Корректно убить поток
Ответ Создать тему
Опции темы

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