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

  • 1,543 views
Uploaded on

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

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

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
1,543
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
58
Comments
1
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. 06 Разбор ДЗ №1 О.В. Сухорослов oleg.sukhoroslov@gmail.com 30.03.2011О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 1 / 32
  • 2. Задача 1.1 - Философы О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 2 / 32
  • 3. Основные ошибки Deadlock Одновременно едят соседи Асимметричное распределение ресурсов О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 3 / 32
  • 4. Устранение взамной блокировки Разный порядок взятия вилок Освобождение вилки в случае неудачной попытки взять обе вилки Допуск к борьбе за вилки не всех философов О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 4 / 32
  • 5. Решения Философы берут вилки в разном порядке Порядок для каждого философа зафиксирован Порядок изменяется после еды О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 5 / 32
  • 6. Решения Пытаться взять вилки с помощью tryLock() Случайная задержка в случае неудачи Случайный порядок взятия вилок О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 6 / 32
  • 7. Решения Допуск к борьбе за вилки не всех философов Глобальная блокировка - в каждый момент времени ест только один философ Очередь голодных философов Фиксированное расписание обедов Семафор - в каждый момент времени борьбу за вилки ведут N-1 философов Официант, выдающий вилки философам О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 7 / 32
  • 8. Решения Синхронизация между соседями Отсутствует глобальный объект синхронизации Busy wait (check, sleep... check, sleep...) Условная синхронизация (wait/notify) О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 8 / 32
  • 9. Решения Выравнивание количества обедов Вилки не даются два раза подряд одному философу Вежливые философы пропускают более голодных соседей (с меньшим кол-вом обедов) Допустимая разница в количестве обедов О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 9 / 32
  • 10. Попытки взять вилки 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 ( I n t e r r u p t e d E x c e p t i o n e ) { break ; }22 }23 } О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 10 / 32
  • 11. Условная синхронизация 1 think (); 2 synchronized ( TABLE ) { 3 state = " HUNGRY " ; 4 while (! canEat ()) { 5 try { 6 TABLE . wait (); 7 } catch ( I n t e r r u p t e d E x c e p t i o n 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
  • 12. Совесть 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
  • 13. Официант 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 ( I n t e r r u p t e d E x c e p t i o n e ) {11 break ;12 } finally {13 philLock . unlock ();14 } О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 13 / 32
  • 14. Альтернативные подходы к concurrency Actors Software Transactional Memory (STM) О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 14 / 32
  • 15. 1Actors Акторы - вычислительные сущности, взаимодействующие с помощью асинхронной отправки сообщений Внутреннее состояние актора скрыто от остальных акторов Акторы могут выполняться независимо друг от друга (одновременно) Реализации Языки Erlang, Io, Scala Библиотека Akka (Java, Scala) http://akka.io/ 1 http://en.wikipedia.org/wiki/Actor_model О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 15 / 32
  • 16. Алгоритм Chandy-Misrahttp://www.cs.utexas.edu/users/misra/scannedPdf.dir/DrinkingPhil.pdf О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 16 / 32
  • 17. 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 . co m pl e te W it hR e su l t ( true );17 } else {18 if (! clean ) {19 clean = true ;20 owner = phil ;21 reply . co m pl e te W it h Re su l t ( true );22 } else {23 reply . co m pl e te W it h Re su l t ( false );24 }25 }26 } else {27 if ( promise == null ) {28 promise = phil ;29 promiseReply = reply ;30 } else {31 reply . co m pl e te W it hR e su l t ( false );32 } О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 17 / 32
  • 18. Fork (2) 1 } else if ( msg_ . equals ( USE )) { 2 if ( phil == owner ) { 3 used = true ; 4 reply . co m pl et e Wi t hR e su l t ( true ); 5 } else { 6 reply . co m pl et e Wi t hR e su l t ( 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 . co m pl e te W it h Re s ul t ( 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 . co m pl e te W it h Re s ul t ( true );27 }28 }29 } else throw new I l l e g a l A r g u m e n t E x c e p t i o n ( " Unknown message : " + msg );30 } else throw new I l l e g a l A r g u m e n t E x c e p t i o n ( " Unknown message : " + msg );31 }32 } О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 18 / 32
  • 19. 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
  • 20. 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 I l l e g a l A r g u m e n t E x c e p t i o n ( " [ " + id + " ] Unknown message : " + msg23 } else throw new I l l e g a l A r g u m e n t E x c e p t i o n ( " [ " + id + " ] Unknown message : " + msg );24 }25 } О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 20 / 32
  • 21. 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 О.В. Сухорослов } () 06 Разбор ДЗ №1 30.03.2011 21 / 32
  • 22. Main 1 public static void main ( String [] args ) { 2 Table table = new Table (5); 3 table . start (); 4 5 try { 6 Thread . sleep (60000); 7 } catch ( I n t e r r u p t e d E x c e p t i o n e ) {} 8 9 table . stop ();10 } О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 22 / 32
  • 23. 2Software Transactional Memory (STM) Механизм управления доступом к общим данным в памяти, аналогичный транзакциям баз данных Atomicity, Consistency, Isolation, (Durability) Optimistic concurrency Реализации Haskell, Clojure, ScalaSTM... 2 http://en.wikipedia.org/wiki/Software_transactional_memory О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 23 / 32
  • 24. 3ScalaSTM 1 class Fork { val inUse = Ref ( false ) } 2 3 def meal ( left : Fork , right : Fork ) { 4 // thinking 5 atomic { implicit txn = > 6 if ( left . inUse () || right . inUse ()) 7 retry // forks are not both ready , wait 8 left . inUse () = true 9 right . inUse () = true10 }11 // eating12 atomic { implicit txn = >13 left . inUse () = false14 right . inUse () = false15 }16 } 3 http://nbronson.github.com/scala-stm/philosophers.html О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 24 / 32
  • 25. Задача 2.1 - Робот О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 25 / 32
  • 26. Характерные времена Загрузки страницы Извлечения ссылок Сохранения страницы на диск Что имеет смысл распараллеливать? О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 26 / 32
  • 27. Поведение CrawlerUtils.getLinks() в VisualVM О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 27 / 32
  • 28. В чем причина? 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 ( M a l f o r m e d U R L E x c e p t i o n e ) {} 9 }10 return links ;11 } О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 28 / 32
  • 29. Решения Блокирующая очередь страниц для загрузки + set для посещенных страниц Управление потоками Одноразовый поток на страницу Число потоков ограничено / неограничено Повторно используемые потоки Собственный пул потоков / Executor Поток порождает дочерние потоки Специализация потоков Загрузка, парсинг, сохранение на диск, добавление новых ссылок в очередь Что делают рабочие потоки, а что - главный? Синхронизация между уровнями поиска Две очереди для загружаемых страниц и новых ссылок О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 29 / 32
  • 30. Детали реализации Использование ExecutorCompletionService4 для получения результатов заданий Ожидание завершения всех заданий5 ExecutorService.awaitTermination() ExecutorService.invokeAll() ExecutorCompletionService Блокирующий Executor для предотвращения переполнения памяти6 Не забываем про executor.shutdown() 4 http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorCompletionService.html 5 http://stackoverflow.com/questions/3269445/executorservice-how-to-wait-for-all-tasks-to-finish 6 http://today.java.net/pub/a/today/2008/10/23/creating-a-notifying-blocking-thread-poolexecutor.html О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 30 / 32
  • 31. Детали реализации Thread safe set CopyOnWriteArraySet ConcurrentSkipListSet Collections.synchronizedSet(Set<T> s) Collections.newSetFromMap(new ConcurrentHashMap<Object,Boolean>()) Использование одного BufferedWriter несколькими потоками thread safe Таймауты соединений в getContent() conn.setConnectTimeout(), conn.setReadTimeout() О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 31 / 32
  • 32. Зависимость скорости от числа потоков О.В. Сухорослов () 06 Разбор ДЗ №1 30.03.2011 32 / 32