Проблемы с многозадачностью
- Войдите на сайт для отправки комментариев
Здравствуйте!
Сразу прошу прощения, если что-то не так, я в первый раз на вашем форуме :)
А теперь к делу. Начал я делать своего роюота, пока с минимальными задачами (объезд препятствий). Все шло хорошо до тех пор, пока я не решил, что неплохо было бы исполнять несколько действий одновременно. В моем случае это моргание двумя светодиодами, движение сервопривода, снятие показаний с HC-SR04 и последующее управление двигателей.
Из всего перечисленного работает все (по примеру BlinkWithoutDelay с использованием классов для определенного действия), но проблема появилась тогда, когда нужно было управлять двигателями. Суть в том, что при получении данных с сонара мы проверяем, больше ли это значение, чем 20 и в зависимости от этого определяем положение серво и едем в нужную сторону.
Помогите пожалуйста разобраться в коде, что не так. Прилагаю код класса, где это происходит.
Заранее спасибо!
class Sweeper { Servo myservo; //Создание объекта myservo int pos; //позиция сервопривода int i; //счетчик массива int increment; //на сколько переместится серво с каждой итерацией цикла int updateInterval; //время между обновлениями public: Sweeper(int interval, int S) { updateInterval = interval; increment = S; } void Attach(int pin) { myservo.attach(pin); myservo.write(0); } void Detach() { myservo.detach(); } void Update() { if((millis() - lastUpdate) > updateInterval) //время обновить! { lastUpdate = millis(); if(i < 9) distance[i] = sonar.ping_cm(); if (distance[i] <= 20) { switch(i) { case 0: {Stop(); go_left(60); }; //в функцию передается ШИМ для двигателей case 1: {Stop(); go_left(60); }; case 2: {Stop(); go_back(60); }; case 3: {Stop(); go_right(60); }; case 4: {Stop(); go_right(60); }; case 5: {Stop(); go_right(60); }; case 6: {Stop(); go_back(60); }; case 7: {Stop(); go_left(60); }; case 8: {Stop(); go_left(60); }; } } i += 1; pos += increment; myservo.write(pos); if((pos >= 180) || (pos <= 0)) //вращать некуда - меняем направление { increment = -increment; // изменение направления } /*if(i == 11) { i = 0; }*/ } } };
Сам вопрос не задан, что именно не так работает?
1. Код с 37 строки "подозрительный".
2. Массив distance внешний, индекс может легко выйти за пределы, кто его знает как он там снаружи описан.
3. i в Update не ограничен. Кстати, называть таким именем переменную - член класса - плохой обычай. Называйте переменные нормальными именами, не экономьте на спичках.
4. С 43 по 51 строки нет ни одного break в switch, почитайте теорию. Фигурные скобки не означают конец case, это в Паскале так было, а в C не так.
UPD: И, да, не называйте это многозадачностью, здесь ОС никакой нет, плоский код, плюс обработчики прерываний - это не многозадачность.
Вопрос как раз был в том, что не так. Спасибо, за break, про него совсем забыл! Про переменные учту. Сейчас исправлю.
Спасибо за подсказку.
Еще есть совет, чтобы не ошибаться, не пишите так, как написано в строках 37-38, заключите 38 строку в фигурные скобки. Компилятору пофиг, а у Вас будет меньше шансов нарваться на ошибку. Например, так:
будет четко видно, что if распространяется только на distance[i] = sonar.ping_cm();, а не на последующие строки.
Т.е. проблема в том, что двигатели не реагируют либо реагируют неверно
Смысл в том, что вопрос понятен только Вам. Вы привели кусочек кода и при этом говорите "двигатели не реагируют либо реагируют не верно", а как они должны реагировать, мы можем только догадываться. Если уже нашли ошибку, то можете и не писать, в чем вопрос.
Это я к тому, что часто люди пишут, что программа "работает не так" и приводят исходник из которого далеко не всегда видно, как она должна работать, плюс нам приходится копаться в скетче (а они порой бывают и по 900 строк), чтобы попытаться понять в чем ошибка.
Это всего лишь советы, чем точнее опишете проблему, тем больше шансов получить корректный ответ ;) А нет - так нет, дело Ваше.
Я понял. Программа должна крутить сервоприводом и на каждой его новой позиции делать замер расстояния сонаром. Сразу же при получении расстояния сверяь с нужной мне и, исходя из этого, крутить двигатели в противоположном направлении. Т.е. такой алгоритм объезда препятствий.
Еще раз прошу прощения за свою неясность ;)
Все, спасибо за подсказки, разобрался! Теперь все работает!
Друзья, решил не пестрить схожими темами, вопрос:
Контроллер поддерживает постоянную температуру и охраняет объект.В момент поддержания температуры, замеры производятся каждые пять минут (одна задача), к примеру происходит разрыв периметра охраны (вторая задача). Контроллер должен отправить смс (третья задача) и начать мигать индикацией (четвертая задача).
Не всегда отправляет смс, как бы замирает (судя по монитору порта).
Может ли быть такое, что контроллер просто не может выполнить такое количество команд одновременно. И что с этим делать.
Контроллер поддерживает постоянную температуру и охраняет объект.
Охрана объекта и параллельно управление самогонным аппаратом? :))))) Круто!
В момент поддержания температуры, замеры производятся каждые пять минут (одна задача), к примеру происходит разрыв периметра охраны (вторая задача). Контроллер должен отправить смс (третья задача) и начать мигать индикацией (четвертая задача).
Может ли быть такое, что контроллер просто не может выполнить такое количество команд одновременно.
Не может. Такие задачи для контроллера - вообще не нагрузка. Он может ещё параллельно футбольным роботом управлять.
И что с этим делать.
Что делать?
Прекратите издеваться над котроллером - он у Вас по 10 секунд сидит в делэях ни хрена при этом не делая. При таком программировании у него и на "помигать 13-м пином" времени не останется.
А если по шагам, то:
1. Забудьте нахрен слово delay - вычеркните его из всех своих файлов-описаний языка. Нет такого слова! Оно противоречит концепции программирования МК
2. Перепишите код так. чтобы не заставлять МК торчать в никому не нужных пустых циклах по пять секунд и он Вас ещё удивит. На Ваших задачах он будет просто простаивать.
Ещё раз - функция delay недопустима ни в каком проекте сложнее, чем помигать 13-м пином. Просто недопустима. Ни в каком контексте. Она отжирает время МК на совершенно ненужный цикл. И отжирает она у Вас тысячами миллисекунд.
А если по шагам, то:
1. Забудьте нахрен слово delay - вычеркните его из всех своих файлов-описаний языка. Нет такого слова! Оно противоречит концепции программирования МК
2. Перепишите код так. чтобы не заставлять МК торчать в никому не нужных пустых циклах по пять секунд и он Вас ещё удивит. На Ваших задачах он будет просто простаивать.
Ещё раз - функция delay недопустима ни в каком проекте сложнее, чем помигать 13-м пином. Просто недопустима. Ни в каком контексте. Она отжирает время МК на совершенно ненужный цикл. И отжирает она у Вас тысячами миллисекунд.
Дружище спасибо за ответ, я не крут в программировании, как ты... Поясни, просто поудалять все строки с delayями кроме тех, что относятся к миганию диода, или надо глобально перелопачивать скетч.
Нет, ну задержки-то Вам нужны, так? Занчит, нужно переписывать код, чьобы эти задержки отрабатывались без блокирования контроллера на всё время задержки. Идея самой просто реализации такого подхода (не самой лучшей, но самой простой) представлена в скетче-примере на этом сайте "блинк без делэй".
Посмотрел я на это и окончательно подзавис, delay все таки сильно упрощало задачу, а из этого я даже не знаю как взять нужное....
.........Забудьте нахрен слово delay - вычеркните его из всех своих файлов-описаний языка. Нет такого слова! Оно противоречит концепции программирования МК........
Не факт.
delay ( 1 ) как и nop иногда очень полезная комманда.
Ну-ка напишите мне её на миллисе?
Главно - знать меру.
Затык в ответе системы начинается с выполнения этой команды
if (sendSMS==false){
sendTextMessage("WARNING! ACHTUNG! ALARM");
sendSMS=true;
может достаточно убрать delay из этого куска
// Контроль периметра!!!
if (isPerimetr) { //Проверка Включен ли контроль периметра
digitalWrite(greenLed, HIGH);
sostPerimetr = digitalRead(perimetr);
if (sostPerimetr==LOW) { //Проверка на разомкнутый периметр
digitalWrite(greenLed, LOW);
delay(2000);
digitalWrite(greenLed, HIGH);
delay(200);
//и отсылаем СМС
if (sendSMS==false){
sendTextMessage("WARNING! ACHTUNG! ALARM");
sendSMS=true;
}
}
} else {
digitalWrite(greenLed, LOW);
}
и наиболее вероятно из этого
*/
void sendTextMessage(String text) {
// Устанавливает текстовый режим для SMS-сообщений
gprsSerial.print("AT+CMGF=1\r");
delay(100); // даём время на усваивание команды
// Устанавливаем адресата: телефонный номер в международном формате
gprsSerial.println("AT + CMGS = \"+7913504\""); //Телефон нужно указать свой
delay(100);
// Пишем текст сообщения
gprsSerial.println(text);
delay(100);
// Отправляем Ctrl+Z, обозначая, что сообщение готово
gprsSerial.println((char)26);
}
//Функция преобразовангия STRING в INT
int stringToNumber(String thisString) {
int i, value = 0, length;
length = thisString.length();
for(i=0; i<length; i++) {
value = (10*value) + thisString.charAt(i)-(int) '0';;
}
return value;
}
.........Забудьте нахрен слово delay - вычеркните его из всех своих файлов-описаний языка. Нет такого слова! Оно противоречит концепции программирования МК........
Не факт.
delay ( 1 ) как и nop иногда очень полезная комманда.
Ну-ка напишите мне её на миллисе?
Главно - знать меру.
А delay(1) - зачем? Заказываешь таймеру прервать тебя через 1 ms и всего делов. Так за эту миллисекунду котроллер столько делов наделает - всё же 16 тысяч тактов. Я никогда не использую делэй - незачем.
Но это другая парадигма программирвания и если с ней не знаком, то к ней нужно привыкать.
Ну а в данном скетче. где делэи местами по 5-10 секунд, ... говорить не о чем.
А попродробней, можете?
"прервать меня через 1мс" - в смысле поднять прогу обработки прерывания - не проблема. Проблема в том, что в ней ничего толкового сделать нельзя. Через 1 мс таймер сработать должен...
А вот именно "прервать", то бишь переключить весь контекст выполнения ... или есть иной способ?
На вопросы многозадачности натыкался много раз, но так и не понял что это такое. Когда несколько светодиодиков смотрят на миллисы и думают не пора ли мне загореться или погаснуть, многозадачностью не считаю. И работа по прерываниям, как мне кажется, это тоже не многозадачность. Похоже на многозадачность, когда я на своем компе, купленном на замену старому, лет 15 назад с какой-то крутой материнкой со встроенной видеокартой, запускал одновременно 5-6 фильмов, и они демонстрировались в 5-6-ти окошках и хором бубнили. Вот это многозадачность. А если по какому-то прерыванию все остановить нахрен....какая это многозадачность?
лет 15 назад с какой-то крутой материнкой со встроенной видеокартой, запускал одновременно 5-6 фильмов, и они демонстрировались в 5-6-ти окошках и хором бубнили. Вот это многозадачность. А если по какому-то прерыванию все остановить нахрен....какая это многозадачность?
Что же касается "что такое много задачность - есть много варианто, но общая идея в том, что каждому процессу даётся некое время на выполнение, затем он прерывается и кусочек времени даётся другому, потом третьему и т.д., но при этом сохраняется контекст, т.е. все регистры, память и т.п., поэтому, когда процесс получат своё кусочек времени, но может и не знать, что его прерывали.
А попродробней, можете?
"прервать меня через 1мс" - в смысле поднять прогу обработки прерывания - не проблема. Проблема в том, что в ней ничего толкового сделать нельзя. Через 1 мс таймер сработать должен...
А вот именно "прервать", то бишь переключить весь контекст выполнения ... или есть иной способ?
Отличный пример - "таблицы решений". Контроллер превращается по сути в конечный автомат, а вся логика программы зашита в матрице переходов между состоянниями. При таком подходе от обработчика прерываний нужно только изменить состояние автомата (че-нить присвоить чему-нибудь). А функция loop - просто длинный case по состояниям и в зависимости от состояния должна что-то сделать и поменять состояние.
При таком подходе нет никакой необходимости ждать чего-то. Достаточно взвести соответсвующее состояние. lopp будет понимать, что ждём (по состоянию). Когда прерывание случится, обработчик поменяет состояниею И ближайший loop начнёт что-то делать уже исходя из нового состояния.
Это не единственный подход, есть другие, но Вы просили пример.
Кстати, сама идея таблиц решений возникла именно для программирования управляющих процессоров (то бишь контроллеров), т.к. она сюда идеально подходит - минимальная нагрузка на контроллер (которые не особо мощный) и вся логика в матрице, т.е. всё легко меняется, если надо. Смею Вас заверить, что управление лифтами в небоскрёбах Манхэттена (за все не скажу, но в Эмпайр Стейт и в печальной памяти WTC - точно) сделано именно на таблицах решений. Управление некоторыми крылатыми ракетами - тоже. Т.е. эта техника широко применяется в контроллерах, она для них и создавалась.
Есть прекрасная книга Хамби. Древняя, но вполне актуальная). Там всё очень понятно изложено. Почитайте, Вам понравится. И наверняка почуствуете, что создавалась эта техника программирования специально для контроллеров - http://www.twirpx.com/file/366454/
А delay(1) - зачем? Заказываешь таймеру прервать тебя через 1 ms и всего делов. Так за эту миллисекунду котроллер столько делов наделает - всё же 16 тысяч тактов. Я никогда не использую делэй - незачем.
Но это другая парадигма программирвания и если с ней не знаком, то к ней нужно привыкать.
Ну а в данном скетче. где делэи местами по 5-10 секунд, ... говорить не о чем.
[/quote]
Сжальтесь, не все такие сообразительные, вы можете просто рассказать, что сделать с этим скетчем. Не взлетая в теории к "парадигмам программирования", и лифтам манхетена.
А у Вас там тоже всё по останавливалось и в каждый конкретный момент выполнялось что-то одно (15 лет назад - наверняка одно ядро было), просто Вы этого не замечали, так как переключалось быстро между задачами и каждая на глаз работала постоянно.
Что же касается "что такое много задачность - есть много варианто, но общая идея в том, что каждому процессу даётся некое время на выполнение, затем он прерывается и кусочек времени даётся другому, потом третьему и т.д., но при этом сохраняется контекст, т.е. все регистры, память и т.п., поэтому, когда процесс получат своё кусочек времени, но может и не знать, что его прерывали.
Полностью согласен. Но нужно еще и расставить приоритеты. Что-то безболезненно можно прервать, а для чего-то -катастрофа.
Да, пасибки. С конечными автоматами - знаком и ваще, их разработка - мое любимое занятие и по сей день. Самый "крутой" делал в 2012году для задачи распознавания "тот же самый товар". Конечный автомат со стековой памятью контекста перехода и программируемым "блоком микропрограммного управления" с автосборкой запроса в Мускуль, по контексту: "как искать похожие товары в БД"... в некоторых ситуациях, даже мне, автору, было не совсем понятно КАК эта зараза принимала решения. :)
Есть что-то готовое на эту тему? Хотя, сваять "ещё один" таблично-управляемый автомат - не проблема. Вот как раз тут, мне кажется что "расширитель SRAM будет ой как к месту. Нарисовал себе страничный контроллер на 7 окон с 8-битным номером страницы (upto 2Mb) ... а мне пишут, что оно "нафиг никому не надо". :)
Кстати, если делать КА с динамически изменяемыми "весами переходов" и целевой функцией "успещно/промах", то получится "самообучаемый" автомат. :)
Помнится у меня, такой играть в "крестики-нолики" учился на уровне "профи" всего ... за около 300 итераций. Ещё на IBM360. А прообраз биржевого бота - делать ставки ... ещё в 1986году ... как раз на "микроконтроллере" (Д3-28, оно же "бортовой вычислитель МИГ-17") :)
Кстати, если делать КА с динамически изменяемыми "весами переходов" и целевой функцией "успещно/промах", то получится "самообучаемый" автомат. :)
А что до табличных процессоров, я не делаю универсального процессора для AVR'ки. Просто при программировании придерживаюсь этой техники. В итоге программа (функция loop) получается как несколько вложенных switch'ей.
вы можете просто рассказать, что сделать с этим скетчем. Не взлетая в теории к "парадигмам программирования", и лифтам манхетена.
Кстати, и ссылка на книгу парой постов выше имеется.
Не взлетая в теории к "парадигмам программирования", и лифтам манхетена.
Вот так и здесь с новичками. Спрашивает как программиировать. Пытаешься объяснить, а тебе в ответ: "не надо философии, просто скажи какую букву где написать". Но программирование - это не писание букв. Если понимать смысл, то можно написать сотней способов, практически любыми "буквами".
Ну, напишу я скрипт за Вас, и что? Вам будет легче писать следующий?
Конечно вытесняющей многозадачностью тут заморочиться не получится, ресурсы не те, но параллельные процессы можно организовать достаточно наглядно.
Я давно использую библиотеку Timer.h оттуда.
Там есть пример использования запуском подпроцессов с разнной периодичностью запуска. Удобно, что при выходе из процесса нужно задать интервал, после которого он должен перезапуститься. При работе возможны погрешности, и весьма приличные, если в процессе глухие циклы , или delay, тк процесс запускается из лупа вызовом t.update, и , пока текущий процесс не завершится, новый не запустится, несмотря на наступление момента запуска.
В целом для задач опросить это раз в 3 секунды, опросить то раз в пять секунд, десять раз в секунду обработать что есть в переменных, выработать результат и применить его к исполнительному устройству , для меня вполне приемлемо. Еще Можно например часто обращаться с проверкой чеготто и , при наличии опрашивать кого нибудь.
Можно управление поместить в лууп, а опросы датчиков проиодят периодически и подбрасывают свежие данные... В общем возможносте масса и главное, что наглядно, легко в использовании и не глючит.
можно еще посмотреть библиотеку Timerone.h но мнеона не пришлась, из-за периодических (раз в нсколько суток) глюков. Однако, если мк живет в цикле ресета, то это не принципиально.
вы можете просто рассказать, что сделать с этим скетчем. Не взлетая в теории к "парадигмам программирования", и лифтам манхетена.
Кстати, и ссылка на книгу парой постов выше имеется.
Не взлетая в теории к "парадигмам программирования", и лифтам манхетена.
Вот так и здесь с новичками. Спрашивает как программиировать. Пытаешься объяснить, а тебе в ответ: "не надо философии, просто скажи какую букву где написать". Но программирование - это не писание букв. Если понимать смысл, то можно написать сотней способов, практически любыми "буквами".
Ну, напишу я скрипт за Вас, и что? Вам будет легче писать следующий?
Нет у меня сейчас времени разбираться, давай брат перенесем объяснение в другую плоскость, комерческую.
Мое мыло: Sharp-news@rambler.ru
Обсудим, ответ нужен "чем быстрее, тем лучше".
давай брат перенесем объяснение в другую плоскость, комерческую.
А программировать лучше научиться, раз уж хотите работать с контроллерами.
Удачи Вам!
Подниму тему.
Вчера, совершенно случайно наткнулся на эту ссылку:
http://ru.wikipedia.org/wiki/%D0%90%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%...
Наверно проще и доходчивее теорию конечных автоматов изложить не удастся, да ещё и с примерами.
Админам форума настоятельно рекомендую выложить содержимое этой ссылки где-то в теории программирования Ардуин.
Я не знаю причин почему типовой Wiring не содержит даже намека на этот подход .. толи по неграмотности толи ещё по каким причинам - не суть в общем-то, но ИМЕННО ТАК и должны программироваться все скетчи, начиная с примитивного blink.ino. И никаких вопросов про "тормознутость проца" возникать не будет... впрочем как и delay() исчезнет "сама собою".
Очень настоятельно рекомендую выложить в раздел программирования.
так и не въехал, вкуда delay() исчезает сама собою?
Очень настоятельно рекомендую выложить в раздел программирования.
ДУмаю что, сразу как выложишь свою новую ИДЕ для AVR камней, там и опубликуем первым делом.
так и не въехал, вкуда delay() исчезает сама собою?
она это.. дизентегрируется :)
Arhat109, Вы правильно поняли, что я имел в виду. Собственно, таблицы решений (одна из реализаций автоматного подхода) - наиболее адекватная вещь для контроллеров. Используется интуитивно и совершенно естественно. Ну, а delay при таком подходе действительно не нужен.
Нда.... А вот мне как-то по барабану есть у меня делэй в скетче или нет. Если мой прототип или законченная игрушка работает так как мне надо. Без тормозов и заскоков. Вы собрались использовать Ардуино в промышленных целях? Нет? И на кой тогда вся эта оптимизация? Ну а если собрались - то Вам в изготовители шлема.
Есть у меня одна поделка, так там ардуина при определенных условиях сама себе питание обрывает перед этим мигая светиком. И зачем мне там менять делэй на что-то?
Не обращайте внимания. Эта школота ничего слаще морковки никогда не видела. Отсюда, от непонимания темы и весь троллизм. :)
Не обращайте внимания. Эта школота ничего слаще морковки никогда не видела. Отсюда, от непонимания темы и весь троллизм. :)
ну куда уж нам то... до вас.. великих переписывателей ИДЕ и разоблачителей разработчиков ардуино.. :) мы так.. белим, красим..
Не обращайте внимания. Эта школота ничего слаще морковки никогда не видела. Отсюда, от непонимания темы и весь троллизм. :)
А у Вас видимо от старческого маразма и глубокого понимания темы твердая увернность в возможности параллельных процессов на ардуине? Нюню
Не обращайте внимания. Эта школота ничего слаще морковки никогда не видела. Отсюда, от непонимания темы и весь троллизм. :)
а, я щитаю, что вся эта херня от русофобии.
А у Вас видимо от старческого маразма и глубокого понимания темы твердая увернность в возможности параллельных процессов на ардуине? Нюню
вроде многозадачность и параллельные процессы - это не одно и тоже.
Дополню.
Собственно эта ссылка - должно быть ПЕРВОЕ, с чем надо знакомится новичку, взявшему в руки Ардуино. И пример с моргалкой светодиодом надо вложить в это описание, переработав его. И delay() -- "всего лишь" одно из состояний автомата-моргалки.
А у Вас видимо от старческого маразма и глубокого понимания темы твердая увернность в возможности параллельных процессов на ардуине? Нюню
вроде многозадачность и параллельные процессы - это не одно и тоже.
Он себя пяткой в грудь колотил что ему на ардуине распараллелить процессы (причем не "псевдо", а по настоящему!) раз чихнуть. Он типа это постоянно делает но никому не показывает - так как тайна сия великая.
Нет там никакой ни многозадачности ни параллелизму в классическом понимании этих терминов... я ж не зря написал "от непонимания" ... читайте пример по ссылке. Там всё разжевано, специально для вас. :)
Да, и не надо приписывать мне свои фантазии от безграмостности... а ежели пишете, то приводите цитаты. :)
Дополню.
Собственно эта ссылка - должно быть ПЕРВОЕ, с чем надо знакомится новичку, взявшему в руки Ардуино. И пример с моргалкой светодиодом надо вложить в это описание, переработав его. И delay() -- "всего лишь" одно из состояний автомата-моргалки.
дополню Дополню - пока ты себе на жопе не сделаешь тату этой статьи, мы не поверим.
Да, и не надо приписывать мне свои фантазии от безграмостности... а ежели пишете, то приводите цитаты. :)
приведи цитаты нашей безграмотности - или звездун.
Да, и не надо приписывать мне свои фантазии от безграмостности... а ежели пишете, то приводите цитаты. :)
пока кроме ваших сексуальных фантазий, в большинстве случаев далеких от реальности, мы ничего не слышали и не видели...
так что продолжайте пытаться выглядеть "умным"... новичкам без разницы.. а нам смешно..
Да где уж нам до Вашего лексикона опускаться. Вам напомнить? Да не вопрос! Все ниже перечисленной с ОДНОЙ(!) ветки.
Цытата от Архата, совсем без плагиата:
"А вот так - это просто тупо позорить Русскую Школу Программистов"
"На иных ресурсах, таких, как ваш бот-троль "пухлявый", банят навсегда на третьем посту, а вы поставили его троллить, типа "круть". Чмошники."
"а после ТАКОГО приема - усретесь!"
"В противном случае, начну заносить ваш форум в известные мне блек-листы. Не надо засорять мне почту."
"он вас "порвет как Тузик грелку""
"Ткак я и попросил ОТПИСАТЬ меня от вашего флуда и говнофорума"
Так вот, прямо тут в этой теме - весь флуд ОТ НЕПОНИМАНИЯ вопросу. :)
пишите исчё, с вами и правда весело. :)
Ну и где тут про "многозадачность", звездун? :)