Russian Qt Forum
Ноябрь 27, 2024, 01:22 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Как можно приостановить процесс ?  (Прочитано 14324 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #15 : Февраль 18, 2010, 16:00 »

Я вот чего подумал - а ведь сам ОС постоянно передает управление от одной нитки к другой. Если напр. я в нитке уйду в глухие вычисления, то ОС ведь не умрет, даже на 1 процессоре. Хммм... и как он это делает? Более того, он делает это довольно быстро, напр. с тем же 1 процессором 8 ниток не будут сильно медленнее чем 4.
Записан
BlackTass
Гость
« Ответ #16 : Февраль 19, 2010, 20:43 »

Я вот чего подумал - а ведь сам ОС постоянно передает управление от одной нитки к другой. Если напр. я в нитке уйду в глухие вычисления, то ОС ведь не умрет, даже на 1 процессоре. Хммм... и как он это делает? Более того, он делает это довольно быстро, напр. с тем же 1 процессором 8 ниток не будут сильно медленнее чем 4.

шедулеры и вытесняющая многозадачность великая вещь не правда ли?)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #17 : Февраль 19, 2010, 21:14 »

шедулеры и вытесняющая многозадачность великая вещь не правда ли?)
Ну эти слова я тоже слышал  Улыбающийся Можно предположить что OS получает управление "по прерыванию от таймера" (как это называлось раньше). Ладно, с учетом приоритетов посчитал кому надо дать процессор(ы) а кого и тормознуть. Ну а дальше-то что? Все равно надо передать управление от нитки к нитке, а для этого переключить стек, восстановить регистры и.т.п. И все это с успехом делается - интересно/полезно было бы узнать как, пусть в общих чертах.
Записан
BRE
Гость
« Ответ #18 : Февраль 19, 2010, 21:50 »

На платформе x86 это делается аппаратно (со времен 80286). Так называемый - защищенный режим процессора.
Есть специальный сегмент, называемый TSS. В нем сохраняется состояние задачи (все регистры, указатели стеков для всех колец защиты и т.д.) и при необходимости служебные данные операционной системы.
По прерыванию от таймеру управление получает планировщик, который принимает решение какую задачу необходимо выполнить следующей, и выполняет инструкцию long jump на селектор новой задачи (jmp это один из способов, также можно сделать call или ret). При прерывании задачи, все ее состояние на аппаратном уровне сохраняется в TSS, а при передачи управления на новую задачу ее состояние загружается из ее TSS.

Записан
sne
Гость
« Ответ #19 : Февраль 20, 2010, 01:49 »

Чисто логические рассуждения, на истину никак не претендующие:
Что-то мне подсказывает, что диспетчеры потоков в ОС все же реализованы программно, состояния регистров каждого из потоков хранятся в глобальной памяти, иначе ограничения ЦПУ накладывали бы ограничения на кол-во потоков, количество которых даже сегодня определяется сотнями. Помимо этого подобная привязка может негативно отразиться на при переносе ОС на какую-либо архитектуру, отличную от х86.

PS
call для передачи управления не очень подходит, т.к. помещает адресс возврата в стек, да и retn тоже не наилучший вариант, т.к. без push'а он в этом качестве бесполезен.

PPS
По теме топика, SuspendThread, ResumeThread, GetThreadContent, SetThreadContent, все это Debug API, а отладчик, на сколько мне помнится, останавливает поток, пусть даже исполняемая команда и находится в критической секции.
Записан
BRE
Гость
« Ответ #20 : Февраль 20, 2010, 09:22 »

Чисто логические рассуждения, на истину никак не претендующие:
Что-то мне подсказывает, что диспетчеры потоков в ОС все же реализованы программно, состояния регистров каждого из потоков хранятся в глобальной памяти, иначе ограничения ЦПУ накладывали бы ограничения на кол-во потоков, количество которых даже сегодня определяется сотнями. Помимо этого подобная привязка может негативно отразиться на при переносе ОС на какую-либо архитектуру, отличную от х86.
Ну так эти сегменты и лежат в обычной памяти и ядро имеет к нему доступ как к обычной структуре.

call для передачи управления не очень подходит, т.к. помещает адрес возврата в стек, да и retn тоже не наилучший вариант, т.к. без push'а он в этом качестве бесполезен.
Современные системы вообще используют малую часть возможностей защищенного режима: используются только 2 кольца защиты из 4, не используются защита на уровне сегментов, ...
Насчет call для переключения, почему не подходит? Выполняется задача, в какой то момент ей нужно запустить другую под-задачу, возможно даже в другом кольце защиты, она вызывает ее через call, когда под-задача завершается, управление возвращается к первой. Тоже можно сделать и с программными прерываниями int.
Возможности у процессора есть, только ими не пользуются... но это и к лучшему, чем меньше проверок будет делать процессор, тем быстрее будет ОС.

Записан
sne
Гость
« Ответ #21 : Февраль 20, 2010, 09:29 »

Насчет call для переключения, почему не подходит? Выполняется задача, в какой то момент ей нужно запустить другую под-задачу, возможно даже в другом кольце защиты, она вызывает ее через call, когда под-задача завершается, управление возвращается к первой.
Я к тому что если эта задача не выполнится до того, как ее вытеснит другая, а в последствии будет продолжена, опять-же call'ом, в стэке будет мусор из адресов возврата. Вот про что я.
Записан
BRE
Гость
« Ответ #22 : Февраль 20, 2010, 09:38 »

Я к тому что если эта задача не выполнится до того, как ее вытеснит другая, а в последствии будет продолжена, опять-же call'ом, в стэке будет мусор из адресов возврата. Вот про что я.
Ну так если задачу будет прерывать планировщик, он и управление будет возвращать не call-ом.
Про call я писал, только чтобы показать что переключать задачи можно разными способами...
Записан
ds40a
Гость
« Ответ #23 : Март 05, 2010, 10:19 »

На этот вопрос нельзя ответить однозначно.

На мой взгляд есть два пути.

1. Если приостановка используется для синхронизации работы потоков, тогда имеет смысл обратить внимание на рекомендацию от Microsoft (MSDN)

Цитировать
Не следует использовать методы Suspend и Resume для синхронизации работы процессов. После приостановления потока невозможно узнать, какой код он выполняет. После приостановления потока во время удержания блокировки и оценки разрешений безопасности другие потоки в AppDomain могут блокироваться. Если поток приостановлен во время выполнения конструктора класса, другие потоки в AppDomain, пытающиеся использовать этот класс, блокируются. Взаимные блокировки могут происходить очень часто.

вот здесь http://lists.trolltech.com/qt-interest/2007-01/thread00346-0.html дан пример реализации class SuspendableThread

2. Если приостановка используется для других целей, тогда это можно "красиво" делать используя DebugAPI для Win, а для Linux нужно "перенимать опыт" у GDB отладчика. Они (отладчики) этим (приостановкой потоков) пользуются очень часто.

P.S. Здесь еще о приостановке потоков http://www.liveinternet.ru/users/optical_race/post76371150/
« Последнее редактирование: Март 05, 2010, 10:38 от ds40a » Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.049 секунд. Запросов: 22.