1 Востаннє редагувалося funivan (05.03.2013 17:21:54)

Тема: Задача на 5+

Як на мене це досить цікава задача для тих хто хоче вивчити детальніше мову php.
Отже умова.
У нас є черга задач. Наприклад 1000 штук. Ми по порядку маємо всіх їх виконати. Якщо задача довго виконується ми її маємо видалити з черги. У нас є ідентифікатор задачі наприклад $id
Сама головна фішка це те що задача може працювати як 1 секунду так і 1000.
Всі задачі які виконуються довше 10 секунд мають видалятись. Фактично це і є головною фішкою.
Видалення з черги і зчитування це все дрібниці головна фішка відслідковувати і видаляти задачу якщо вона працює довше 10 секунд


Ось кусок коду. Все що вам потрібно зробити це написати логіку яка буде виконувати видалення задачі, якщо та працює більше 10 секунд.

$maxItems = 1000;
for ($i = 0; $i<= $maxItems; $i++) {
  $task = new Task($i);
  if($task->run()){
    $task->delete();
  }
}

Удачі ;)

Оновлено: Тобто якщо задача виконується 11 секунд зупиняти і видаляти задачу з черги

Re: Задача на 5+

Я так розумію, що після десяти секунд треба робити переривання, та видаляти
чи видаляти вже тоді коли завдання завершиться ?

3

Re: Задача на 5+

Hanter написав:

Я так розумію, що після десяти секунд треба робити переривання, та видаляти
чи видаляти вже тоді коли завдання завершиться ?

Після 10 секунд потрібно робити переривання.

Час виконання задачі може бути і 10000 секунд.

4 Востаннє редагувалося Адріян Ігорович (05.03.2013 16:00:21)

Re: Задача на 5+

funivan написав:

Після 10 секунд потрібно робити переривання.

Зараз я можливо щось таке нерозумне скажу та все ж..
Можливо можна спробувати заюзати microtime(), та перевіряти
скільки часу пройшло від запуску ?
Поки що, інших варіантів не бачу.

5

Re: Задача на 5+

Зараз я можливо щось таке нерозумне скажу та все ж..
Можливо можна спробувати заюзати microtime(), та перевіряти
скільки часу пройшло від запуску ?
Поки що, інших варіантів не бачу.

Спробуйте =) І киньте сюди код ;)

Re: Задача на 5+

Ніби щось вийшло, зараз скину код.

7 Востаннє редагувалося Адріян Ігорович (05.03.2013 16:44:56)

Re: Задача на 5+

Ну ось вийшло таке:

Прихований текст

<?php

set_time_limit(0);

 $taskList = array(100,25000,35000,10000,280,12333);

 Class Task
 {
          
  function Run($taskID,$taskList,$numIteration)
  {
      //start
        $start_counter = microtime();
        $start_counter_array = explode(" ",$start_counter);
        $start_counter = $start_counter_array[1] + $start_counter_array[0];
     //end
    
    for($i = 0;$i < $numIteration; $i++)
     {
      for($i2 = 0; $i2 < 500; $i2++)
       {
        for($i3 = 0; $i3 < 100; $i3++)    
         {} 
       }
       //start
        $stop_counter = microtime();
        $stop_counter_array = explode(" ",$stop_counter);
        $stop_counter = $stop_counter_array[1] + $stop_counter_array[0];
        $time_generation_page = $stop_counter - $start_counter;
         //end
         if(round($time_generation_page,5) > 10)
          { $this->Remove($taskID,$taskList); return 1; }
          
     }  
    return 0; 
  }    
  
  function Remove($taskID,$taskList)
  {
     unset($taskList[$taskID]); 
  } 
 }


 $task = new Task();
 
  for($counter = 0; $counter < count($taskList); $counter++)
  {
     if($task->Run($counter,$taskList,$taskList[$counter]) == 0)
      echo "Завдання з номером ".$counter." завершилося успішно. \n";
     else
      echo "Виконання завдання під номером ".$counter." було перервано. \n"; 
  }
?>

Результат такий:

Завдання з номером 0 завершилося успішно. 
Виконання завдання під номером 1 було перервано. 
Виконання завдання під номером 2 було перервано. 
Виконання завдання під номером 3 було перервано. 
Завдання з номером 4 завершилося успішно. 
Виконання завдання під номером 5 було перервано. 

P.S: не кидайте сильно помідорами за код, а особливо за
рахувайлик який обчислює скільки секунд виконується...
Взяв його ще зі старих скриптів.

Re: Задача на 5+

Поправка. Дякую funivan.
Новий код:

Прихований текст

<?php

set_time_limit(0);

 $taskList = array(0,1,2,3,4,5,6,7,8,9);

 Class Task
 {
          
  function Run($taskID,$taskList)
  {
      //start
        $start_counter = microtime();
        $start_counter_array = explode(" ",$start_counter);
        $start_counter = $start_counter_array[1] + $start_counter_array[0];
     //end
         sleep($taskID*2);    
       //start
        $stop_counter = microtime();
        $stop_counter_array = explode(" ",$stop_counter);
        $stop_counter = $stop_counter_array[1] + $stop_counter_array[0];
        $time_generation_page = $stop_counter - $start_counter;
         //end
         if(round($time_generation_page,5) > 10)
          { $this->Remove($taskID,$taskList); return 1; }
         else 
          return 0; 
  }    
  
  function Remove($taskID,$taskList)
  {
     unset($taskList[$taskID]); 
  } 
 }


 $task = new Task();
 
  for($counter = 0; $counter < count($taskList); $counter++)
  {
     if($task->Run($counter,$taskList) == 0)
      echo "Завдання з номером ".$counter." завершилося успішно. \n";
     else
      echo "Виконання завдання під номером ".$counter." було перервано. \n"; 
  }


?>

9

Re: Задача на 5+

Код робочий але або я не правильно висловився або не правильно мене зрозуміли.
Має бути така штука яка перериває задачу. Тобто задача або виконується менше 10 секунд або її видаляить. Тобто якщо у нас є 10 задач максимальний час виконання 10*10=100
Тобто у нас має бути скрипт який не чекає виконання задачі до кінця а видаляє її з черги. І більше задача не запуститься ;)

10

Re: Задача на 5+

funivan написав:

Має бути така штука яка перериває задачу. Тобто задача або виконується менше 10 секунд або її видаляить.

Що ж, подумаємо.

11

Re: Задача на 5+

має бути реалізовано одним класом?)

pew pew :D
Блоґ

12 Востаннє редагувалося funivan (05.03.2013 17:50:16)

Re: Задача на 5+

має бути реалізовано одним класом?)

Класів може бути декілька.

13

Re: Задача на 5+

Є два варіанти - нить і процес. Ниті вбивати без їх волі негарно, тому що вони можуть не встигнути звільнити ресурс. Значить потрібно в циклі задачі постійно робити перевірку чи не просять задачу поступитись місцем, і виконувати код для завершення в такому випадку.

Якщо ж доступу до задачі ми не маємо, тоді залишається покластись на можливості витісняючої багатозадачності ОС. Засікаємо час, запускаємо новий процес з задачею, іноді перевіряємо чи він ще живий, і чи не потрібно замістити іншим процесом, а якщо час вийшов - KILL DASH NINE і готово!

14

Re: Задача на 5+

На скільки я зрозумів, ви хочете, щоб скрипт, який обробляє, і задачі виконувались паралельно. Як на мене це трохи суперечить парадигмі PHP.
Можна правда поізвращатись з запуском кількох процесів і встановленням якогось ідентифікатора, наприклад в базі даних чи в мемкеші.
Я правильно зрозумів?

15

Re: Задача на 5+

Радий такій активності в темі :)
Отже все по порядку.
2bunyk: фактично я теж думав над цією реалізацією тобто у нас є один головний процес який запускає дочірні і слідкує за виконанням, але я пішов іншим шляхом. Була задача обробляти безмежну кількість листів. Використовував модуль із Zend Замітив що деколи черга зависає на одному і тому ж листі так як то проблеми з мережею або лист якийсь покоцаний або дуже великий не ясно. Перевіривши декілька раз виявилось що дійсно на одному листі час обробки більше 2х хвилин. Ось і довелось якось перевіряти час обробки.

2 Vo_Vik: Ні, на даному етапі не було потрібно паралельності задачі. Хоча це цілком можливий варіант такої роботи.

Дам підказку. Я пішов таким шляхом: треба якось щось запускати/викликати ф-цію коли дохне скрипт, нехай навіть він дохне через 40 хвилин але ми маємо врешті решт видалити цю дурну задачу і що б більше вона не повторилась. Наступним кроком треба якось пришвидшити цю дію що б не чекати 40 хвилин.

Ще раз до Вовіка: те що ламає парадигму можливо ви праві але ви ж не будете заради швидкого виконання задач (які можна успішно виконати паралельно на рнр) розробляти на інших мовах =)

16

Re: Задача на 5+

Ну якщо ти таких хочеш вбивати процеси, то як варіант в файлі відправки листів
set_time_limit(10);
А сам файл визивати через cURL або CLI. Але це таки не буде чистий php. Це буде кілька паралельних процесів php.
Якби set_time_limit(10) опрацьовувався try-catch, то там ще би можна було пофантазувати.

17

Re: Задача на 5+

Якби set_time_limit(10) опрацьовувався try-catch, то там ще би можна було пофантазувати.

Ну так try-catch не опрацьовує але взагалі фактично його опрацювати можна ;) Що я і зробив. А про курл це не туди) У мене це все 1н скрипт і він сам себе не визиває тілкьи запускається кожні 5 хвилин) Якщо уже запущений тоді не стартує.
Отже set_time_limit(10) це правильний шлях )

18

Re: Задача на 5+

Ну так що народ писати відгадку ?:) ;)

19

Re: Задача на 5+

Та давай, бо логіка зрозуміла, залишились деталі)

20

Re: Задача на 5+

Щось я нічого не зрозумів :)
Взагалі в php багатопоточності немає. А для мене задача - це окремий потік зі своїми ресурсами. Є лише curl multi. Можна викликати самого себе кілька разів через curl з різними параметрами, а вбивати за рахунок використання set_time_limit (точніше вони вже самі будуть вмирати :)).

А взагалі що з себе представляє задача?