1 of 26

Многопоточность и сокеты

2 of 26

Процессор

обрабатывает операции на ядрах

Ядро — главное вычислительное устройство

В один момент на ядре выполняется только одна операция

Частота процессора — �кол-во операций в секунду

2

3 of 26

Процесс, поток

Процесс — запущенная программа

Поток (thread, нить) — последовательность операций, выполняемых в ОС

В одном процессе может быть несколько потоков

Примеры:

  • «Слушаю музыку, работаю в ворде» – 2 процесса
  • «Работаю в ворде – редактирую документ, пока он отправляется на печать» – 1 процесс, 2 потока

3

Лекции про многопоточность, 1 курс 2017, Абрамский М.М.

4 of 26

Переключение контекста

Как куча операций в компьютере выполняется параллельно? �Не все так параллельно

Переключением контекста занимается операционная системы

4

5 of 26

Переключение контекста на нескольких ядрах

5

6 of 26

Thread

“Одновременный” запуск двух потоков

threads_simple.py

6

7 of 26

Race condition (состояние гонки)

Поток надеется, что исходные данные еще не поменялись, а они уже поменялись

7

8 of 26

Thread Event

Потокобезопасный механизм общения между разными потокам

threads_events.py

8

9 of 26

Thread Lock

Устанавливает блокировку, чтобы другие потоки не делали ничего во время выполнения операции

threads_locks.py

9

10 of 26

Deadlock

10

11 of 26

Пример — 2010

def countdown(n):

while n > 0:

n -= 1

count = 100000000 # 100 million

countdown(COUNT)

t1 = Thread(target=countdown,args=(COUNT//2,))

t2 = Thread(target=countdown,args=(COUNT//2,))

t1.start(); t2.start()

t1.join(); t2.join()

Итоги

7.8 с — Последовательно

15.4 с — 2 потока�15.7 с — 4 потока:

11.3 с — 2 потока на одном CPU�11.6 с — 4 потока на одном CPU

11

12 of 26

Пример — 2020

def countdown(n):

while n > 0:

n -= 1

count = 10000

countdown(COUNT)

t1 = Thread(target=countdown,args=(COUNT//2,))

t2 = Thread(target=countdown,args=(COUNT//2,))

t1.start(); t2.start()

t1.join(); t2.join()

8 потоков

Итоги

0.00041 с — последовательно

0.00114 с — 8 потоков

12

13 of 26

Global Interpreter Lock (GIL)

Threads в Python не дают параллельность. В Python всегда один выполняемый поток.

Это сделано для избежания состояния гонки (race condition)

13

14 of 26

Работает только одно ядро

14

15 of 26

Работают все ядра

15

16 of 26

multiprocessing — используем всю мощь CPU

Запускается несколько python-процессов, в которые работают параллельно

16

17 of 26

multiprocessing — используем всю мощь CPU

Запускается несколько python-процессов, в которые работают параллельно

threads_multiproc_simple.py

17

18 of 26

multiprocessing — данные

Передача данных:

  • до/после процесса
  • очереди
  • общие объекты (ctypes objects)

threads_multiproc_mem.py

18

19 of 26

multiprocessing — Pool

Запуск и остановка процесса — долгая операция. �Нужно переиспользовать уже запущенные процессы

threads_multiproc_pool.py

19

20 of 26

Задача

Написать консольную программу, которая принимает адрес страницы и многопоточно скачивает все картинки с этой страницы в папку

Время: 20 минут

20

21 of 26

sockets

21

22 of 26

Протоколы TCP vs UDP

22

23 of 26

Протоколы TCP vs UDP

23

Картинка из https://9gag.com/gag/an5d7xV

24 of 26

socket

низкоуровневый интерфейс для сетевого общения

  • bind — привязка к адресу
  • listen — прослушивание адреса
  • accept — прием сообщения
  • connect — подключение
  • send — отправка
  • recv — прием
  • close — до свидания

24

25 of 26

Лайфхак

Получение IP устройства в локальной сети

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.connect(("8.8.8.8", 80))

ip = s.getsockname()[0]

s.close()

25

26 of 26

Задача на дом

Написать текстовую игру “Борьба”

  • К серверу подключаются два игрока
  • При запуске клиента запросить имя игрока
  • Игроки бьют друг друга с помощью команды kick NAME, �где NAME - имя игрока
  • Если имя введено неверно, нужно попросить пользователя ввести правильное имя
  • Ход выполняется по очереди
  • Количество очков, которые снимаются при ударе, будет рандомным от 1 до 10

26