courses:high_performance_computing:producer_consumer
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
courses:high_performance_computing:producer_consumer [2018/10/07 12:48] – kel | courses:high_performance_computing:producer_consumer [2019/02/27 06:58] – kel | ||
---|---|---|---|
Line 7: | Line 7: | ||
- N потоков consumer | - N потоков consumer | ||
На стандартный ввод программе подается строка - список чисел, разделённых пробелом. Длина списка чисел не задаётся - считывание происходит до перевода каретки. | На стандартный ввод программе подается строка - список чисел, разделённых пробелом. Длина списка чисел не задаётся - считывание происходит до перевода каретки. | ||
- | * Задача producer-потока - получить на вход список чисел, и по очереди использовать каждое значение из этого списка для обновления переменной разделяемой между потоками. После этого поток должен дождаться реакции одного из consumer-потоков, | + | * Задача producer-потока - получить на вход список чисел, и по очереди использовать каждое значение из этого списка для обновления переменной разделяемой между потоками |
- | * Задача consumer-потоков отреагировать на каждое изменение | + | * Задача consumer-потоков отреагировать на уведомление от producer |
+ | - Функция, исполняющая код этого потока consumer_routine, должна принимать указатель на объект/переменную, из которого будет | ||
+ | - После суммирования переменной поток должен заснуть на случайное количество миллисекунд, | ||
+ | - Потоки consumer не должны дублировать вычисления друг с другом одних и тех же значений | ||
+ | - В качестве возвращаемого значения поток должен вернуть свою частичную посчитанную сумму | ||
+ | - Хранить промежуточные значения своей суммы поток должен в TLS-переменной, | ||
* Задача потока-interruptor проста: | * Задача потока-interruptor проста: | ||
- | Функция run_threads должна запускать все потоки, | + | Функция run_threads должна запускать все потоки, |
- | + | ||
- | Для обновления и получения значения следует использовать подготовленный класс Value. Следует создать один экземпляр Value, передать его аргументом в функции producer_routine и consumer_routine. Чтобы обновить значение, следует использовать метод update, чтобы получить - get | + | |
Для обеспечения межпоточного взаимодействия допускается использование только pthread API. На вход приложения передаётся 2 аргумента при старте именно в такой последовательности: | Для обеспечения межпоточного взаимодействия допускается использование только pthread API. На вход приложения передаётся 2 аргумента при старте именно в такой последовательности: | ||
- Число потоков consumer | - Число потоков consumer | ||
- Верхний предел сна consumer в миллисекундах | - Верхний предел сна consumer в миллисекундах | ||
+ | |||
+ | В поток вывода должно попадать только результирующее значение, | ||
<file cpp> | <file cpp> | ||
#include < | #include < | ||
- | |||
- | class Value { | ||
- | public: | ||
- | Value() : _value(0) { } | ||
- | |||
- | void update(int value) { | ||
- | _value = value; | ||
- | } | ||
- | |||
- | int get() const { | ||
- | return _value; | ||
- | } | ||
- | |||
- | private: | ||
- | int _value; | ||
- | }; | ||
void* producer_routine(void* arg) { | void* producer_routine(void* arg) { | ||
Line 42: | Line 31: | ||
// Read data, loop through each value and update the value, notify consumer, wait for consumer to process | // Read data, loop through each value and update the value, notify consumer, wait for consumer to process | ||
- | |||
} | } | ||
void* consumer_routine(void* arg) { | void* consumer_routine(void* arg) { | ||
// notify about start | // notify about start | ||
- | // allocate value for result | ||
// for every update issued by producer, read the value and add to sum | // for every update issued by producer, read the value and add to sum | ||
- | // return pointer to result | + | // return pointer to result |
} | } | ||
void* consumer_interruptor_routine(void* arg) { | void* consumer_interruptor_routine(void* arg) { | ||
- | // wait for consumer | + | // wait for consumers |
- | // interrupt consumer while producer is running | + | // interrupt |
} | } | ||
courses/high_performance_computing/producer_consumer.txt · Last modified: 2024/03/04 02:19 by odoronin