Название: Как можно приостановить процесс ? Отправлено: QtProger от Февраль 10, 2010, 17:55 Как с Qt приостановить процесс какой-нибудь программы по имени процесса ?
Название: Re: Как можно приостановить процесс ? Отправлено: BlackTass от Февраль 10, 2010, 19:53 если под никсами то зовешь ps ax | grep process_name, парсишь его вывод, берешь оттуда pid и зовешь kill -9 pid
Это если наверняка надо. Если же просто послать сигнал завершения (который не обязательно завершит процесс), то killall process_name Название: Re: Как можно приостановить процесс ? Отправлено: QtProger от Февраль 10, 2010, 20:04 если под никсами то зовешь ps ax | grep process_name, парсишь его вывод, берешь оттуда pid и зовешь kill -9 pid Я слышал что Qt кроссплатформенна.... Это если наверняка надо. Если же просто послать сигнал завершения (который не обязательно завершит процесс), то killall process_name Завершать не надо, надо приостановить, чтобы потом можно было продолжить с прерванного места Название: Re: Как можно приостановить процесс ? Отправлено: BlackTass от Февраль 11, 2010, 20:17 Qt конечно кроссплатформенна, но подобные вещи являются уж совсем не кроссовыми и возможными не на всех платформах (на винде насколько я помню это недокументированная функция ntdll).
Название: Re: Как можно приостановить процесс ? Отправлено: Igors от Февраль 15, 2010, 07:21 Завершать не надо, надо приостановить, чтобы потом можно было продолжить с прерванного места Процесс имеет хотя бы 1 нитку (thread), как ее остановить? Или даже: как процесс может остановить одну из своих же ниток? Да никак, можно только послать событие, выставить флаг и.т.п. полагая что код, выполняющийся в нитке, это "поймет" и перейдет напр. в ожидание на семафоре. Но если нитка этого не делает - заставить ее нечем. То же и с процессом.Название: Re: Как можно приостановить процесс ? Отправлено: sne от Февраль 15, 2010, 08:28 в никсах - черт его знает, а в винде:
По идее должно работать. Название: Re: Как можно приостановить процесс ? Отправлено: Павел_F. от Февраль 15, 2010, 09:35 Это, опять же, только "порекомендует" потоку остановиться. Но не заставит. Реакцию на такое предложение поток определит сам для себя. Никто не заставить поток встать. Гарантированно его можно только убить. Все остальное будет зависит от самого потока, как он написан, в какой момент ему придет это "предложение" подождать и т.д.
Название: Re: Как можно приостановить процесс ? Отправлено: niXman от Февраль 15, 2010, 09:48 чтоб остановить поток/процесс, нужно сохранить его контекст, и и изъять его из списка обрабатываемых контекстов.
в никсах есть АПИ уровня ядра, но его невозможно использовать из прикладного уровня, сами понимаете. не вкурсе если в вендах такое есть, но думаю что нет. ибо не должно такого быть. если же есть надобность в подобном, это однозначно говорит об ошибке проектирования. Название: Re: Как можно приостановить процесс ? Отправлено: sne от Февраль 15, 2010, 23:20 Это, опять же, только "порекомендует" потоку остановиться. Но не заставит. Реакцию на такое предложение поток определит сам для себя. Никто не заставить поток встать. Гарантированно его можно только убить. Все остальное будет зависит от самого потока, как он написан, в какой момент ему придет это "предложение" подождать и т.д. Это далеко не предложение :) Если удастся открыть поток с нужными правами и функция SuspendThread вернет положительный результат - поток остановлен, факт.Название: Re: Как можно приостановить процесс ? Отправлено: Павел_F. от Февраль 16, 2010, 08:38 Если удастся открыть поток с нужными правами и функция SuspendThread вернет положительный результат - поток остановлен, факт. Если удастся и если вернет это гарантированный результат? Я весь поток могу написать одной большой критической секцией. Не встанет он. А автор темы хочет чужие потоки тормозить. При этом не зная кто они и зачем нужны. Если я напишу прогу которая, например, реализует четыре потока( у меня четыре ядра) каждому потоку я скажу что он может выполнятся только на конкретном ядре, три потока будут считать а четвертый для синхронизации прочей служебной фигни. Что будет если какой-нибудь негодяй остановит поток для синхронизации??? Правильно или "мы все умрем" или фиг ему а не приостановка потока.Название: Re: Как можно приостановить процесс ? Отправлено: Igors от Февраль 16, 2010, 10:52 Это далеко не предложение :) Если удастся открыть поток с нужными правами и функция SuspendThread вернет положительный результат - поток остановлен, факт. Ладно, расширим наш багаж знаний, читаем MSDNЦитировать This function is primarily designed for use by debuggers. It is not intended to be used for thread synchronization. Calling SuspendThread on a thread that owns a synchronization object, such as a mutex or critical section, can lead to a deadlock if the calling thread tries to obtain a synchronization object owned by a suspended thread. To avoid this situation, a thread within an application that is not a debugger should signal the other thread to suspend itself. The target thread must be designed to watch for this signal and respond appropriately. Оно конечно, "нет преград энтузиастам", но мне кажется - связываться с таким мутным делом не резон, скорее всего не остановим, а покалечим. Ну и кросс-платформенностью там и не пахнет. Напр. в Posix такого точно нет Название: Re: Как можно приостановить процесс ? Отправлено: sne от Февраль 16, 2010, 12:58 Павел_F, если поток программы выполняющий приостановку потоков выполняется, то в любом случае, в твоем примере не все потоки работают ;) Че тут, пробовать надо, а не рассуждать о страшных последствиях :) К тому же ситуация частная, и такое встретить в реальной жизни - шанс маленький. Способ не идеален, я не спорю, но вполне рабочий.
Igors, в дедлок оно попадет при условии что: а) используются объекты синхронизации (почти всегда часто) б) мы останавливаем 1 поток с объектом синхронизации (тоже вполне может быть, и что?) Разумеется остальные потоки будут ждать приостановленного нами. Но в конце концов мы же его запустим, вероятно не плохо бы при этом соблюсти порядок стэка для ResumeThread. ЗЫ Помимо критики, уважаемые, могут предлагать способы получше, либо меры по улучшению данного решения ;) ЗЗЫ На счет кроссплатформенности, внимательно выше: в никсах - черт его знает, а в винде: Название: Re: Как можно приостановить процесс ? Отправлено: Alex Custov от Февраль 17, 2010, 07:08 если под никсами то зовешь ps ax | grep process_name, парсишь его вывод, берешь оттуда pid и зовешь kill -9 pid kill -STOP <pid> продолжить - kill -CONT <pid> Название: Re: Как можно приостановить процесс ? Отправлено: Igors от Февраль 17, 2010, 23:18 Че тут, пробовать надо, а не рассуждать о страшных последствиях :) Попробовать-то не вредно, только вот заказчику я бы такую фичу не обещал - потому как не знаю что мне ему ответить если он спросит "Я за это заплатил, а оно вылетает, а на той платформе вообще не работает. Исправляйте как хотите, это Ваши проблемы". Исходный вопрос надо понимать "есть ли легальная, кросс-платформенная возможность остановить процесс средствами Qt?" (пусть автор меня поправит если не так). Нормальный ответ на этот вопрос: нет, такой возможности нет. А хотите делать используя нативные средства ОС (крутизну показать) - дело Ваше, но это может дорого Вам обойтись. Название: Re: Как можно приостановить процесс ? Отправлено: sne от Февраль 18, 2010, 09:41 [floodMode]
Исходный вопрос надо понимать "есть ли легальная, кросс-платформенная возможность остановить процесс средствами Qt?" (пусть автор меня поправит если не так). Нормальный ответ на этот вопрос: нет, такой возможности нет. В Qt много чего нет, прослезитесь, но посмотрите исходники, того же самого qextSerialPort многострадального. Работы с последовательными портами в Qt тоже нет, и posix порт там реализован далеко не идеально, но когда кого это останавливало?А хотите делать используя нативные средства ОС (крутизну показать) - дело Ваше, но это может дорого Вам обойтись. Не хотим, но есть такое слово как "надо", и против "надо", извините, не попрешь.[/floodMode] Заканчиваю флуд и более на подобные провокации не откликаюсь. Кто с чем не согласен, в личку, будьте добры, там мне не кому будет "крутизну показать". Спасибо за внимание, всегда Ваш, возмущенный sne. :) Название: Re: Как можно приостановить процесс ? Отправлено: Igors от Февраль 18, 2010, 16:00 Я вот чего подумал - а ведь сам ОС постоянно передает управление от одной нитки к другой. Если напр. я в нитке уйду в глухие вычисления, то ОС ведь не умрет, даже на 1 процессоре. Хммм... и как он это делает? Более того, он делает это довольно быстро, напр. с тем же 1 процессором 8 ниток не будут сильно медленнее чем 4.
Название: Re: Как можно приостановить процесс ? Отправлено: BlackTass от Февраль 19, 2010, 20:43 Я вот чего подумал - а ведь сам ОС постоянно передает управление от одной нитки к другой. Если напр. я в нитке уйду в глухие вычисления, то ОС ведь не умрет, даже на 1 процессоре. Хммм... и как он это делает? Более того, он делает это довольно быстро, напр. с тем же 1 процессором 8 ниток не будут сильно медленнее чем 4. шедулеры и вытесняющая многозадачность великая вещь не правда ли?) Название: Re: Как можно приостановить процесс ? Отправлено: Igors от Февраль 19, 2010, 21:14 шедулеры и вытесняющая многозадачность великая вещь не правда ли?) Ну эти слова я тоже слышал :) Можно предположить что OS получает управление "по прерыванию от таймера" (как это называлось раньше). Ладно, с учетом приоритетов посчитал кому надо дать процессор(ы) а кого и тормознуть. Ну а дальше-то что? Все равно надо передать управление от нитки к нитке, а для этого переключить стек, восстановить регистры и.т.п. И все это с успехом делается - интересно/полезно было бы узнать как, пусть в общих чертах.Название: Re: Как можно приостановить процесс ? Отправлено: BRE от Февраль 19, 2010, 21:50 На платформе x86 это делается аппаратно (со времен 80286). Так называемый - защищенный режим процессора.
Есть специальный сегмент, называемый TSS. В нем сохраняется состояние задачи (все регистры, указатели стеков для всех колец защиты и т.д.) и при необходимости служебные данные операционной системы. По прерыванию от таймеру управление получает планировщик, который принимает решение какую задачу необходимо выполнить следующей, и выполняет инструкцию long jump на селектор новой задачи (jmp это один из способов, также можно сделать call или ret). При прерывании задачи, все ее состояние на аппаратном уровне сохраняется в TSS, а при передачи управления на новую задачу ее состояние загружается из ее TSS. Название: Re: Как можно приостановить процесс ? Отправлено: sne от Февраль 20, 2010, 01:49 Чисто логические рассуждения, на истину никак не претендующие:
Что-то мне подсказывает, что диспетчеры потоков в ОС все же реализованы программно, состояния регистров каждого из потоков хранятся в глобальной памяти, иначе ограничения ЦПУ накладывали бы ограничения на кол-во потоков, количество которых даже сегодня определяется сотнями. Помимо этого подобная привязка может негативно отразиться на при переносе ОС на какую-либо архитектуру, отличную от х86. PS call для передачи управления не очень подходит, т.к. помещает адресс возврата в стек, да и retn тоже не наилучший вариант, т.к. без push'а он в этом качестве бесполезен. PPS По теме топика, SuspendThread, ResumeThread, GetThreadContent, SetThreadContent, все это Debug API, а отладчик, на сколько мне помнится, останавливает поток, пусть даже исполняемая команда и находится в критической секции. Название: Re: Как можно приостановить процесс ? Отправлено: BRE от Февраль 20, 2010, 09:22 Чисто логические рассуждения, на истину никак не претендующие: Ну так эти сегменты и лежат в обычной памяти и ядро имеет к нему доступ как к обычной структуре.Что-то мне подсказывает, что диспетчеры потоков в ОС все же реализованы программно, состояния регистров каждого из потоков хранятся в глобальной памяти, иначе ограничения ЦПУ накладывали бы ограничения на кол-во потоков, количество которых даже сегодня определяется сотнями. Помимо этого подобная привязка может негативно отразиться на при переносе ОС на какую-либо архитектуру, отличную от х86. call для передачи управления не очень подходит, т.к. помещает адрес возврата в стек, да и retn тоже не наилучший вариант, т.к. без push'а он в этом качестве бесполезен. Современные системы вообще используют малую часть возможностей защищенного режима: используются только 2 кольца защиты из 4, не используются защита на уровне сегментов, ...Насчет call для переключения, почему не подходит? Выполняется задача, в какой то момент ей нужно запустить другую под-задачу, возможно даже в другом кольце защиты, она вызывает ее через call, когда под-задача завершается, управление возвращается к первой. Тоже можно сделать и с программными прерываниями int. Возможности у процессора есть, только ими не пользуются... но это и к лучшему, чем меньше проверок будет делать процессор, тем быстрее будет ОС. Название: Re: Как можно приостановить процесс ? Отправлено: sne от Февраль 20, 2010, 09:29 Насчет call для переключения, почему не подходит? Выполняется задача, в какой то момент ей нужно запустить другую под-задачу, возможно даже в другом кольце защиты, она вызывает ее через call, когда под-задача завершается, управление возвращается к первой. Я к тому что если эта задача не выполнится до того, как ее вытеснит другая, а в последствии будет продолжена, опять-же call'ом, в стэке будет мусор из адресов возврата. Вот про что я.Название: Re: Как можно приостановить процесс ? Отправлено: BRE от Февраль 20, 2010, 09:38 Я к тому что если эта задача не выполнится до того, как ее вытеснит другая, а в последствии будет продолжена, опять-же call'ом, в стэке будет мусор из адресов возврата. Вот про что я. Ну так если задачу будет прерывать планировщик, он и управление будет возвращать не call-ом.Про call я писал, только чтобы показать что переключать задачи можно разными способами... Название: Re: Как можно приостановить процесс ? Отправлено: ds40a от Март 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/ |