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

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

Войти
Регистрация
Восстановить пароль
 
DiffEreD
1429 / 766 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
#1

Исключения в потоках - C++

19.03.2013, 14:24. Просмотров 476. Ответов 7
Метки нет (Все метки)

Кто читал книгу Параллельное программирование на С++ в действии; у меня возник вопрос из 8 главы. Какая роль в нижеприведенном коде класса join_threads, зачем потоки присоединять в деструкторе при исключении? Программа же все равно будет прервана при первом срабатывании исключения, а те потоки, которые еще работают сами по себе и завершатся при уничтожении вектора потоков threads с соответствующими им вызовами terminated. Или это такой "правильный" стиль программирования автор книги хочет нам показать?
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <thread>
#include <future>
#include <stdexcept>
 
class join_threads
{
    std::vector<std::thread>& threads;
public:
    explicit join_threads(std::vector<std::thread>& threads_): threads(threads_) {}
    ~join_threads()
    {
        for (unsigned long i = 0; i<threads.size(); ++i)
        {
            if (threads[i].joinable())
            {
                std::cout<<"thread joined\n";
                threads[i].join();
            }
                
        }
    }
};
 
template<typename Iterator,typename Func>
void parallel_for_each(Iterator first,Iterator last,Func f)
{
    unsigned long const length=std::distance(first,last);
 
    if(!length)
        return;
 
    unsigned long const num_threads = std::thread::hardware_concurrency();
 
    unsigned long const block_size=length/num_threads;
 
    std::vector<std::future<void> > futures(num_threads);
    std::vector<std::thread> threads(num_threads);
    join_threads joiner(threads);
 
    Iterator block_start=first;
    for(unsigned long i=0;i<num_threads;++i)
    {
        Iterator block_end=block_start;
        std::advance(block_end,block_size);
        std::packaged_task<void(void)> task([=](){std::for_each(block_start,block_end,f);});
        futures[i]=task.get_future();
        threads[i]=std::thread(std::move(task));
        block_start=block_end;
    }
    std::for_each(block_start,last,f);
    for(unsigned long i=0;i<num_threads;++i)
    {
        futures[i].get();
    }
}
 
void oops(const unsigned i)
{ 
    if (i == 0) throw std::out_of_range("i == 0") ;
    std::cout<<i<<"\n";
}
 
int main()
{
    std::vector<int> v = {30,31,32,33,34,0,36,37,38,39,0};
    try
    {
        parallel_for_each(v.begin(), v.end(), oops);
    }
    catch(const std::out_of_range& oor)
    {
        std::cerr << "Out of Range error: " << oor.what() << '\n';
    }
    
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.03.2013, 14:24     Исключения в потоках
Посмотрите здесь:

Литература о потоках - C++
Хотел бы найти хорошую книгу в которой хорошо изложены вопросы паралельного программирования. В класичиской литературе которую проходил...

Линейный поиск в потоках - C++
кому не сложно и у кого есть IDE просто посмотрите прикрепленный проект не понимаю где ошыбка... имееться базовый класс MyThread...

Не могу разобраться в потоках - C++
Есть программа которая считывает строку с файла и переводит в Азбуку Морзе,вроде бы всеправильнонаписано но почему то не выполняется...

2 цикла в разных потоках - C++
Здравствуйте! Научите! Как правильно делать &quot;что-то&quot; в отдельном фоновом потоке в C++. Пожалуйста код! К примеру: void...

Одинаковый id в двух потоках - C++
#include&lt;iostream&gt; #include&lt;thread&gt; using namespace std; class background_task { public: int l; background_task(int i)...

Как в потоках вводить текст? - C++
Вот пример,как я ввожу числа,для работы с ними void sozdanie() { char x; cout &lt;&lt; &quot;\nВведите имя файла&quot;; cin &gt;&gt; x; cout &lt;&lt;...

Отсутствует перемещаемый конструктор в потоках - C++
Добрый день. Отвечая на вопрос в одной теме столкнулся с тем, что g++ отказался перемещать поток, ссылаясь на то, что, мол,...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Tulosba
:)
Эксперт С++
4392 / 3235 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
19.03.2013, 14:52     Исключения в потоках #2
Цитата Сообщение от yuron_477 Посмотреть сообщение
зачем потоки присоединять в деструкторе при исключении?
Не очень понимаю, почему Вы связываете деструктор с исключением. Деструктор вызывается и при правильной работе, когда объект выходит из области видимости например.
-=ЮрА=-
Заблокирован
Автор FAQ
19.03.2013, 15:21     Исключения в потоках #3
Цитата Сообщение от yuron_477 Посмотреть сообщение
зачем потоки присоединять в деструкторе при исключении?
там нет никакого исключения, деструктор необходим чтобы после прекращения использования класса
Цитата Сообщение от yuron_477 Посмотреть сообщение
class join_threads
его потоки закрылись (как я понимаю
Цитата Сообщение от yuron_477 Посмотреть сообщение
threads[i].join();
- это метод для закрытия потока)
0x10
2459 / 1631 / 238
Регистрация: 24.11.2012
Сообщений: 4,009
19.03.2013, 15:30     Исключения в потоках #4
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- это метод для закрытия потока)
Для закрытия? Join блокирует текущий поток до тех пор пока не завершится поток, представленный объектом thread.
DiffEreD
1429 / 766 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
19.03.2013, 15:42  [ТС]     Исключения в потоках #5
Цитата Сообщение от Tulosba Посмотреть сообщение
Не очень понимаю, почему Вы связываете деструктор с исключением
Да просто глава, где автор книги его использовал называется "Делаем код безопасным относительно исключений"(с.346)
Вот цытата:
Осталось решить проблему утечки потоков в случае, когда исклю¬
чение возникает между моментом запуска первого потока и присо¬
единением всех запущенных. Для этого проще всего перехватить лю¬
бое исключение, дождаться присоединения потоков, которые все еще
находятся в состоянии joinable(), а потом возбудить исключение
повторно:
Автор сначала делает перехват исключений в блоках try/catch в самой функции parallel_for_each (я так понял из контекста), а потом решает вместо этого запихнуть все это дело в класс join_threads. Вот и мне не совсем ясно его решение.
Tulosba
:)
Эксперт С++
4392 / 3235 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
19.03.2013, 15:59     Исключения в потоках #6
Цитата Сообщение от yuron_477 Посмотреть сообщение
Осталось решить проблему утечки потоков в случае, когда исклю¬
чение возникает между моментом запуска первого потока и присо¬
единением всех запущенных.
Т.е. в первом варианте, который
Цитата Сообщение от yuron_477 Посмотреть сообщение
делает перехват исключений в блоках try/catch в самой функции parallel_for_each
была утечка в случае исключения, или автор просто модифицирует код, путем добавления объекта с деструктором?
-=ЮрА=-
Заблокирован
Автор FAQ
19.03.2013, 16:47     Исключения в потоках #7
Цитата Сообщение от 0x10 Посмотреть сообщение
Для закрытия? Join блокирует текущий поток до тех пор пока не завершится поток, представленный объектом thread.
- ну хорошо пусть WaitFor а не ExitThread

Цитата Сообщение от yuron_477 Посмотреть сообщение
~join_threads()
* * {
* * * * for (unsigned long i = 0; i<threads.size(); ++i)
* * * * {
* * * * * * if (threads[i].joinable())
* * * * * * {
* * * * * * * * std::cout<<"thread joined\n";
* * * * * * * * threads[i].join();
* * * * * * }
}
* * }
- значит в свете этого уточнения

Цитата Сообщение от 0x10 Посмотреть сообщение
Join блокирует текущий поток до тех пор пока не завершится поток, представленный объектом thread.
- десктруктор организует нечто наподобие WaitForSingleObject где нити ожидают завершения главного потока.
Пока хоть убей не пойму где гениться исключение - предположу что jonable это SetEvent т.е установква события ядра (EVENT). EVENT может не установиться потому снова предполагаю это состояние приводит к исключению.

Не по теме:

Собственно на АПИ такое распараллеливание через ивенты делается в 3-4 строки, без всей тучи кода выше.

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.03.2013, 17:04     Исключения в потоках
Еще ссылки по теме:

MSVC - читаем файл в 2х потоках - C++
Привет! Устал бороться с MSVC, может я чего-то не вижу, помогите найти ошибку (пример очень упрощенный) struct manager { ...

Строки в консоли и файлах(потоках).Зацикливание - C++
Задание: Создать файл записей с полями: название улицы, количество зданий на этой улице, год возникновения названия улицы. Подсчитать и...

Безопасное использование вектора в двух потоках - C++
Это продолжение этой темы , но уже немного другая проблема. Работаю с классом , который создаёт объекты через shared_ptr и заносит их в...

Движение двух фигур в разных потоках - C++
Привет всем!всех с новым годом!и снова я к вам с моими проблемами) короче пишу игрушку в консоле,столкнулся впервые с...

Найти буквы от а - я. Кодировка в файловых потоках - C++
Доброго времени суток. Есть некая строка (char*) и функция bool RusArray(char c) { for (int i = 'а'; i &lt;= 'я'; ++i) { ...


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

Или воспользуйтесь поиском по форуму:
ForEveR
В астрале
Эксперт С++
7969 / 4731 / 320
Регистрация: 24.06.2010
Сообщений: 10,539
Завершенные тесты: 3
19.03.2013, 17:04     Исключения в потоках #8
Суть: во время выполнения различных операций в коде может вылететь исключение. Чтобы не отлавливать его и не завершать потоки вручную (ибо вызов деструктора на joinable потоке приведет к std::terminate) сделан guard, который заботится об этом. Как только объект join_threads выходит из области видимости - будет вызван его деструктор, все потоки будут корректно завершены, если join не выкинет исключения конечно же.
Yandex
Объявления
19.03.2013, 17:04     Исключения в потоках
Ответ Создать тему
Опции темы

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