32

Click here to load reader

О.В.Сухорослов "Разбор ДЗ №1"

  • Upload
    yandex

  • View
    1.790

  • Download
    9

Embed Size (px)

DESCRIPTION

О.В.Сухорослов "Разбор ДЗ №1", 30.03.2012, место показа МФТИ, Школа анализа данных (ШАД)

Citation preview

Page 1: О.В.Сухорослов "Разбор ДЗ №1"

06 Разбор ДЗ №1

О.В. Сухорослов

[email protected]

30.03.2011

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 1 / 32

Page 2: О.В.Сухорослов "Разбор ДЗ №1"

Задача 1.1 - Философы

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 2 / 32

Page 3: О.В.Сухорослов "Разбор ДЗ №1"

Основные ошибки

Deadlock

Одновременно едят соседи

Асимметричное распределение ресурсов

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 3 / 32

Page 4: О.В.Сухорослов "Разбор ДЗ №1"

Устранение взамной блокировки

Разный порядок взятия вилок

Освобождение вилки в случае неудачной попытки взять обе вилки

Допуск к борьбе за вилки не всех философов

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 4 / 32

Page 5: О.В.Сухорослов "Разбор ДЗ №1"

Решения

Философы берут вилки в разном порядкеПорядок для каждого философа зафиксированПорядок изменяется после еды

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 5 / 32

Page 6: О.В.Сухорослов "Разбор ДЗ №1"

Решения

Пытаться взять вилки с помощью tryLock()Случайная задержка в случае неудачиСлучайный порядок взятия вилок

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 6 / 32

Page 7: О.В.Сухорослов "Разбор ДЗ №1"

Решения

Допуск к борьбе за вилки не всех философовГлобальная блокировка - в каждый момент времени ест толькоодин философОчередь голодных философовФиксированное расписание обедовСемафор - в каждый момент времени борьбу за вилки ведут N-1философовОфициант, выдающий вилки философам

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 7 / 32

Page 8: О.В.Сухорослов "Разбор ДЗ №1"

Решения

Синхронизация между соседямиОтсутствует глобальный объект синхронизацииBusy wait (check, sleep... check, sleep...)Условная синхронизация (wait/notify)

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 8 / 32

Page 9: О.В.Сухорослов "Разбор ДЗ №1"

Решения

Выравнивание количества обедовВилки не даются два раза подряд одному философуВежливые философы пропускают более голодных соседей (сменьшим кол-вом обедов)Допустимая разница в количестве обедов

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 9 / 32

Page 10: О.В.Сухорослов "Разбор ДЗ №1"

Попытки взять вилки

1 public class Fork extends ReentrantLock {}2 ...3 boolean hungry = true;4 while (hungry) {5 left.lock ();6 try {7 if (right.tryLock ()) {8 try {9 eat ();

10 hungry = false;11 } finally {12 right.unlock ();13 }14 }15 } finally {16 left.unlock ();17 }18 if (hungry) {19 try {20 Thread.sleep (10 + rnd.nextInt (10));21 } catch (InterruptedException e) { break; }22 }23 }

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 10 / 32

Page 11: О.В.Сухорослов "Разбор ДЗ №1"

Условная синхронизация

1 think ();2 synchronized (TABLE) {3 state = "HUNGRY";4 while (! canEat ()) {5 try {6 TABLE.wait ();7 } catch (InterruptedException e) {8 break;9 }

10 }11 state = "EATING";12 }13 eat ();14 synchronized (TABLE) {15 state = "THINKING";16 TABLE.notifyAll ();17 }

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 11 / 32

Page 12: О.В.Сухорослов "Разбор ДЗ №1"

Совесть

1 private boolean canEat () {2 if (LEFT.state.equals("EATING") ||3 RIGHT.state.equals("EATING")) {4 return false;5 }6 if (LEFT.state.equals("HUNGRY") &&7 eatCount - LEFT.eatCount > 10) {8 return false;9 }

10 if (RIGHT.state.equals("HUNGRY") &&11 eatCount - RIGHT.eatCount > 10) {12 return false;13 }14 return true;15 }

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 12 / 32

Page 13: О.В.Сухорослов "Разбор ДЗ №1"

Официант

1 think ();2 philLock.lock ();3 try {4 waiter.makeOrder(this);5 while (! canEat)6 condition.await ();7 eat ();8 canEat = false;9 waiter.thanks(this);

10 } catch (InterruptedException e) {11 break;12 } finally {13 philLock.unlock ();14 }

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 13 / 32

Page 14: О.В.Сухорослов "Разбор ДЗ №1"

Альтернативные подходы к concurrency

Actors

Software Transactional Memory (STM)

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 14 / 32

Page 15: О.В.Сухорослов "Разбор ДЗ №1"

Actors 1

Акторы - вычислительные сущности, взаимодействующие спомощью асинхронной отправки сообщенийВнутреннее состояние актора скрыто от остальных акторовАкторы могут выполняться независимо друг от друга(одновременно)

РеализацииЯзыки Erlang, Io, ScalaБиблиотека Akka (Java, Scala)

http://akka.io/

1http://en.wikipedia.org/wiki/Actor_modelО.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 15 / 32

Page 16: О.В.Сухорослов "Разбор ДЗ №1"

Алгоритм Chandy-Misra

http://www.cs.utexas.edu/users/misra/scannedPdf.dir/DrinkingPhil.pdf

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 16 / 32

Page 17: О.В.Сухорослов "Разбор ДЗ №1"

Fork

1 public class Fork extends UntypedActor {2 ...3 public void onReceive(Object msg) throws Exception {4 ActorRef phil = getContext (). getSender ().get ();5 CompletableFuture <Object > reply = null ;6 if (getContext (). getSenderFuture (). isDefined ()) {7 reply = getContext (). getSenderFuture ().get ();8 }9 if (msg instanceof String) {

10 String msg_ = (String)msg;11 if (msg_.equals(TAKE)) {12 if (! used) {13 if (owner == null) {14 owner = phil;15 } else if (phil == owner) {16 reply.completeWithResult (true);17 } else {18 if (!clean) {19 clean = true ;20 owner = phil ;21 reply.completeWithResult(true);22 } else {23 reply.completeWithResult(false );24 }25 }26 } else {27 if (promise == null) {28 promise = phil ;29 promiseReply = reply ;30 } else {31 reply.completeWithResult(false );32 }

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 17 / 32

Page 18: О.В.Сухорослов "Разбор ДЗ №1"

Fork (2)

1 } else if (msg_.equals(USE)) {2 if (phil == owner) {3 used = true;4 reply.completeWithResult(true);5 } else {6 reply.completeWithResult(false );7 }8 } else if (msg_.equals(USED)) {9 if (phil == owner) {

10 used = false;11 clean = false;12 if (promise != null) {13 clean = true;14 owner = promise;15 promise = null;16 promiseReply.completeWithResult(true);17 }18 }19 } else if (msg_.equals(NOT_USED )) {20 if (phil == owner) {21 used = false;22 if (promise != null) {23 clean = true;24 owner = promise;25 promise = null;26 promiseReply.completeWithResult(true);27 }28 }29 } else throw new IllegalArgumentException("Unknown message: " + msg);30 } else throw new IllegalArgumentException("Unknown message : " + msg);31 }32 }

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 18 / 32

Page 19: О.В.Сухорослов "Разбор ДЗ №1"

Philosopher

1 public class Philosopher extends UntypedActor {2 ...3 public Philosopher(int id, ActorRef left , ActorRef right) {4 ...5 if (id == 0) {6 left.sendOneWay(Fork.TAKE , me);7 right.sendOneWay(Fork.TAKE , me);8 } else if (id != size -1) {9 left.sendOneWay(Fork.TAKE , me);

10 }11 }

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 19 / 32

Page 20: О.В.Сухорослов "Разбор ДЗ №1"

Philosopher (2)

1 public void onReceive(Object msg) throws Exception {2 if (msg instanceof String) {3 String msg_ = (String)msg ;4 if (msg_.equals(THINK)) {5 System.out.println("["+id+"] Thinking");6 Scheduler.scheduleOnce(me , START_EAT , 0, TimeUnit.MILLISECONDS );7 } else if (msg_.equals(START_EAT )) {8 if (( Boolean)left.sendRequestReply(Fork.TAKE , me)9 && (Boolean)right.sendRequestReply(Fork.TAKE , me)

10 && (Boolean)left.sendRequestReply(Fork.USE , me)11 && (Boolean)right.sendRequestReply(Fork.USE , me)) {12 System.out.println("["+id+"] Eating");13 Scheduler.scheduleOnce(me , FINISH_EAT , 0, TimeUnit.MILLISECONDS );14 } else {15 left.sendOneWay(Fork.NOT_USED , me);16 Scheduler.scheduleOnce(me , START_EAT , 0, TimeUnit.MILLISECONDS );17 }18 } else if (msg_.equals(FINISH_EAT )) {19 left.sendOneWay(Fork.USED , me);20 right.sendOneWay(Fork.USED , me);21 Scheduler.scheduleOnce(me , THINK , 0, TimeUnit.MILLISECONDS );22 } else throw new IllegalArgumentException("["+id+"] Unknown message : " + msg);23 } else throw new IllegalArgumentException ("["+id+"] Unknown message : " + msg);24 }25 }

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 20 / 32

Page 21: О.В.Сухорослов "Разбор ДЗ №1"

Table

1 public class Table {2 ...3 public Table(int philCount) {4 forks = new ArrayList <ActorRef >( philCount );5 for (int i=0; i<philCount; i++) {6 ActorRef fork = Actors.actorOf(new ForkFactory(i));7 forks.add(fork);8 fork.start ();9 }

10 phils = new ArrayList <ActorRef >( philCount );11 for (int i=0; i<philCount; i++) {12 ActorRef phil = Actors.actorOf(13 new PhilFactory (i, (i==philCount -1) ? forks.get(0) : forks.get(i+1)),14 forks.get(i));15 phils.add(phil);16 phil.start ();17 }18 }1920 public void start () {21 for (ActorRef phil : phils) {22 phil.sendOneWay(Philosopher.THINK);23 }24 }2526 public void stop () {27 for (ActorRef phil : phils) {28 phil.stop ();29 }30 for (ActorRef fork : forks) {31 fork.stop ();32 }33 }34 }

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 21 / 32

Page 22: О.В.Сухорослов "Разбор ДЗ №1"

Main

1 public static void main (String [] args) {2 Table table = new Table (5);3 table.start ();45 try {6 Thread.sleep (60000);7 } catch (InterruptedException e) {}89 table.stop ();

10 }

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 22 / 32

Page 23: О.В.Сухорослов "Разбор ДЗ №1"

Software Transactional Memory (STM) 2

Механизм управления доступом к общим данным в памяти,аналогичный транзакциям баз данныхAtomicity, Consistency, Isolation, (Durability)Optimistic concurrency

РеализацииHaskell, Clojure, ScalaSTM...

2http://en.wikipedia.org/wiki/Software_transactional_memoryО.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 23 / 32

Page 24: О.В.Сухорослов "Разбор ДЗ №1"

ScalaSTM 3

1 class Fork { val inUse = Ref(false) }23 def meal(left: Fork , right: Fork) {4 // thinking5 atomic { implicit txn =>6 if (left.inUse () || right.inUse ())7 retry // forks are not both ready , wait8 left.inUse() = true9 right.inUse() = true

10 }11 // eating12 atomic { implicit txn =>13 left.inUse() = false14 right.inUse() = false15 }16 }

3http://nbronson.github.com/scala-stm/philosophers.htmlО.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 24 / 32

Page 25: О.В.Сухорослов "Разбор ДЗ №1"

Задача 2.1 - Робот

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 25 / 32

Page 26: О.В.Сухорослов "Разбор ДЗ №1"

Характерные времена

Загрузки страницыИзвлечения ссылокСохранения страницы на диск

Что имеет смысл распараллеливать?

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 26 / 32

Page 27: О.В.Сухорослов "Разбор ДЗ №1"

Поведение CrawlerUtils.getLinks() в VisualVM

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 27 / 32

Page 28: О.В.Сухорослов "Разбор ДЗ №1"

В чем причина?

1 public static Set <URL > getLinks(URL url , String content) {2 Set <URL > links = new HashSet <URL >();3 Matcher matcher = linkPattern.matcher(content );4 while (matcher.find ()) {5 try {6 URL link = new URL(url , matcher.group (1));7 links.add(link);8 } catch (MalformedURLException e) {}9 }

10 return links;11 }

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 28 / 32

Page 29: О.В.Сухорослов "Разбор ДЗ №1"

Решения

Блокирующая очередь страниц для загрузки + set дляпосещенных страниц

Управление потокамиОдноразовый поток на страницу

Число потоков ограничено / неограниченоПовторно используемые потоки

Собственный пул потоков / Executor

Поток порождает дочерние потоки

Специализация потоковЗагрузка, парсинг, сохранение на диск, добавление новых ссылок вочередьЧто делают рабочие потоки, а что - главный?

Синхронизация между уровнями поискаДве очереди для загружаемых страниц и новых ссылок

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 29 / 32

Page 30: О.В.Сухорослов "Разбор ДЗ №1"

Детали реализации

Использование ExecutorCompletionService4 для получениярезультатов заданий

Ожидание завершения всех заданий5

ExecutorService.awaitTermination()ExecutorService.invokeAll()ExecutorCompletionService

Блокирующий Executor для предотвращения переполненияпамяти6

Не забываем про executor.shutdown()

4http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorCompletionService.html5http://stackoverflow.com/questions/3269445/executorservice-how-to-wait-for-all-tasks-to-finish6http://today.java.net/pub/a/today/2008/10/23/creating-a-notifying-blocking-thread-

poolexecutor.html

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 30 / 32

Page 31: О.В.Сухорослов "Разбор ДЗ №1"

Детали реализации

Thread safe setCopyOnWriteArraySetConcurrentSkipListSetCollections.synchronizedSet(Set<T> s)Collections.newSetFromMap(newConcurrentHashMap<Object,Boolean>())

Использование одного BufferedWriter несколькими потокамиthread safe

Таймауты соединений в getContent()conn.setConnectTimeout(), conn.setReadTimeout()

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 31 / 32

Page 32: О.В.Сухорослов "Разбор ДЗ №1"

Зависимость скорости от числа потоков

О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 32 / 32