- •Начало
- •Использование многопоточности
- •Проблемы многопоточности
- •Реентрабельность
- •Локальное хранилище потока
- •Поддержка многопоточности в C ++
- •Библиотеки многопоточности
- •Потоки
- •Мьютексы
- •Блокировки
- •Условные переменные, барьеры
- •Способы обеспечения безопасности потоков
- •Синхронизация на уровне объектов
- •Синхронизация в стандартной библиотеке
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Прежний подход к программированию потоков
Пример (базовый класс) |
|
Пример (пользовательский класс) |
|
||
class Thread |
|
class MyThread : public Thread |
{ |
|
{ |
public: |
|
protected: |
void Run(); |
|
virtual void OnExecute(); |
bool IsRunning() const; |
|
private: |
// . . . |
|
Data m_Data1; |
protected: |
|
// . . . |
virtual void OnExecute() = 0; |
|
} |
}; |
|
|
|
|
|
Лекция 8 |
11 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Использование библиотеки потоков
Пример (Boost)
#include <boost/thread/thread.hpp>
using namespace boost;
Пример (C++0x)
#include <thread>
using namespace std;
Лекция 8 |
12 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Пространство имён this_thread
Общие методы
thread::id get_id()
void yield()
Лекция 8 |
13 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Пространство имён this_thread, функции сна
Boost
template <typename TimeDuration>
void sleep(TimeDuration const &rcTime);
C++0x
template <class Clock, class Duration>
void sleep_until(const chrono::time_point <Clock, Duration> &);
template <class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period> &);
Лекция 8 |
14 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Класс thread
Методы (создание, перемещение)
thread();
template <typename Callable> [explicit ]thread(Callable func);
template <class F, class A1, class A2, ...>
thread(F f, A1 a1, A2 a2, ...); (Boost, до 9 параметров)
template <class F, class ... Args>
thread(F &&, Args && ...); (C++0x, variadic template parameters)
Семантика перемещения, обмен.
Лекция 8 |
15 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Шаблоны с переменным количеством параметров
Определение std::tuple <> (C++0x)
template <> class tuple <>
{
public:
void swap(tuple &&)
{
// Пусто
}
};
Лекция 8 |
16 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Шаблоны с переменным количеством параметров
Определение std::tuple (C++0x)
template <typename Head, typename ... Tail>
class tuple <Head, Tail ...> : private tuple <Tail ...>
{
typedef tuple <Tail ...> inherited; protected:
Head m_head; public:
tuple(
typename add_const_reference <Head>::type rcH, typename add_const_reference <Tail>::type ... rcT)
: m_head(rcH), inherited(rcT ...) { |
} |
typename add_reference <Head>::type |
head() { return m_head; } |
inherited &tail() { return *this; } |
// . . . |
Лекция 8 |
17 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Использование списков типов
Пример
#include <tuple>
// . . .
using namespace std;
int main()
{
string s = "Hello";
vector <int> v = {1, 22, 3, 4, 5}; auto x = make_tuple(s, v, 1.2);
// tuple <string, vector <int>, double> x = ...
cout << get <0> (x) << endl;
// . . .
Лекция 8 |
18 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Рекурсивная обработка списков (Пролог)
Пример
all_positive([]).
all_positive([Head | Tail]) :- Head > 0, all_positive(Tail).
Пример (запрос)
?- all_positive([3, 1, 5]). yes
Лекция 8 |
19 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Класс thread (окончание)
Методы (владение, слияние)
void detach();
thread::id get_id() const;
native_handle_type native_handle();
bool joinable() const; (get_id() != id())
void join();
bool timed_join(const system_time &rcAbsTime); (Boost)
template <typename TimeDuration>
bool timed_join(TimeDuration const &rcRelTime); (Boost)
static unsigned hardware_concurrency();
Лекция 8 |
20 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Использование потоков
Пример
#include <boost/thread/thread.hpp>
void thread_func()
{
// . . .
}
struct ThreadData
{
Data m_Data;
void operator () ();
};
Пример (окончание)
using namespace boost;
int main()
{
// . . .
thread thread1(thread_func);
// . . .
ThreadData data; thread thread2(data);
// . . .
}
Лекция 8 |
21 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Потоки на некопируемых объектах
Пример
struct Callable
{
Callable() {}
void operator () ()
{
// . . .
}
private:
Callable(const Callable &);
};
Пример (окончание)
int main()
{
// . . .
Callable callable; boost::thread thread1(
boost::ref(callable));
// . . .
thread1.join();
// . . .
}
Лекция 8 |
22 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Потоки с некопируемыми параметрами
Пример
struct Callable
{
Callable() {}
void operator () (int &rn)
{
// . . .
++ rn;
}
private:
Callable(const Callable &);
};
Пример (окончание)
int main()
{
// . . .
int n = 10; boost::thread thread2(
boost::ref(callable),
n);
thread2.join();
cout << "n == " << n << endl;
// . . .
}
Лекция 8 |
23 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Потоки с некопируемыми параметрами
Пример
struct Callable
{
Callable() {}
void operator () (int &rn)
{
// . . .
++ rn;
}
private:
Callable(const Callable &);
};
Пример (окончание)
int main()
{
// . . .
int n = 10; boost::thread thread2(
boost::ref(callable), boost::ref(n));
thread2.join();
cout << "n == " << n << endl;
// . . .
}
Лекция 8 |
23 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Передача локальных буферов в потоки
Пример (функция потока) |
|
Пример (вызов) |
|
||
struct Callable |
|
void call(int n) |
{ |
|
{ |
void operator () ( |
|
char szBuf[1024]; |
const std::string &rcStr) |
|
std::sprintf( |
{ |
|
szBuf, "%d", n); |
boost::this_thread::sleep( |
|
boost::thread thread( |
boost::posix_time::milliseconds(500)); |
|
Callable(), szBuf); |
std::cout << rcStr << std::endl; |
|
thread.detach(); |
} |
|
} |
}; |
|
|
|
|
|
Лекция 8 |
24 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Передача локальных буферов в потоки
Пример (функция потока) |
|
Пример (вызов) |
|
||
struct Callable |
|
void call(int n) |
{ |
|
{ |
void operator () ( |
|
char szBuf[1024]; |
const std::string &rcStr) |
|
std::sprintf( |
{ |
|
szBuf, "%d", n); |
boost::this_thread::sleep( |
|
std::string s(szBuf); |
boost::posix_time::milliseconds(500)); |
|
boost::thread thread( |
std::cout << rcStr << std::endl; |
|
Callable(), s); |
} |
|
thread.detach(); |
}; |
|
} |
|
|
|
Лекция 8 |
24 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Прерывание потоков
Пример
int main()
{
// . . .
boost::thread thread3(thread_func2);
// . . .
thread3.interrupt();
}
Лекция 8 |
25 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Предопределённые точки прерывания
Вызовы функций
boost::thread::join()
boost::thread::timed_join()
boost::condition_variable::wait()
boost::condition_variable::timed_wait()
boost::condition_variable_any::wait()
boost::condition_variable_any::timed_wait()
boost::thread::sleep()
boost::this_thread::sleep()
boost::this_thread::interruption_point()
Лекция 8 |
26 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Потоки с непрерываемыми участками
Пример
void thread_func0()
{
// . . .
try
{
// . . .
}
catch (const boost::thread_interrupted &)
{
// . . .
}
// . . .
}
Лекция 8 |
27 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Потоки с непрерываемыми участками
Пример
void thread_func1()
{
// . . .
{
boost::this_thread::disable_interruption di;
// . . .
{
boost::this_thread::disable_interruption di2;
// . . .
}
// . . .
}
// . . .
Лекция 8 |
27 / 55 |
Начало |
Потоки |
Использование многопоточности |
Мьютексы |
Библиотеки многопоточности |
Блокировки |
Способы обеспечения безопасности потоков |
Условные переменные, барьеры |
Потоки с непрерываемыми участками
Пример
void thread_func2()
{
// . . .
{
boost::this_thread::disable_interruption di;
// . . .
{
boost::this_thread::restore_interruption ri(di);
// . . .
}
// . . .
}
// . . .
Лекция 8 |
27 / 55 |