Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.10.2012, 12:36   #1
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию Многократная приостановка и возобновление выполнения процеса

Здраствуйте. У меня задача по лабе создать некое подобие деспетчера управления процесами. Там создается очередь выполнения и каждому процесу нужно давать по небольшому промежутку времени на выполнение, а потом если процес не выполнился полностью, приостановить его, поместить в конец очереди(в противном случае его нужно удалить из очереди). потом опять когда дойдет очередь до этого же процеса, его выполнение нужно возобновить. и так до тех пор пока он не выполнется.
Собсно вопрос: как сделать само прерывание выполнения процеса и последущее возобновление?
я пробовал так:
Код:
// ...
    #define MAX_PROCESS_TIME 10
// ...
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
 
    ZeroMemory(&si, sizeof(STARTUPINFO));
    CreateProcess(NULL, "calc.exe", NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
 
    ResumeThread(pi.hThread);
    DWORD call_result = WaitForSingleObject(pi.hProcess, MAX_PROCESS_TIME);
    if(call_result == WAIT_OBJECT_0){
        // процес выполнился и тд.. удаляем его из очереди
    } else {
        // значит процес не выполнился полностью
        // хотя он может и выполнится с ошибкой,
        // ибо в call_result может быть еще несколько констант 
        SuspendThread(pi.hThread);
        // приостановил выполенение.. помещаю его в конец очереди
    }
// ...
чтото на подобии этого выполнятся циклично до тех пор пока очередь не будет пустой.
все что мне нужно это правильно приостановить процес, а потом возобновить с того же места, ненадо никаких очередей делать. это все у меня уже есть. все работатет если выполнять WaitForSingleObject(pi.hProcess, INFINITE); но так не годится! а вдруг выполнение процеса затянется на 30 минут!? нет. надо прервать и дать другим пощупать процесор пальчиками
подскажите, пожалуйста, как будет правильние реализировать подобную задачу на winapi?
заранее спасибо
lowercase вне форума Ответить с цитированием
Старый 08.10.2012, 12:42   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

процесс не исполняет код, исполняет код поток.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 08.10.2012, 13:05   #3
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

То, что вы написали будет работать только с процессами, которые не создают дополнительных потоков. Вам нужно просматривать список всех потоков процесса и останавливать их, причем делать это несколько раз, на предмет появления новых потоков, причем старые уже замороженные не надо трогать. И все равно, если поток сделал несколько раз ResumeThread то вы его не остановите. Иными словами 100% решения вашей проблемы нет

Лучше посмотрите в сторону SetPriorityClass().
Уж не знаю, что делают ваши процессы, но раз их надо останавливать лучше переделать процессы так, чтоб не надо было их останавливать.
waleri вне форума Ответить с цитированием
Старый 08.10.2012, 13:33   #4
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

эм.. процесы точно однопотоквые. ибо этот диспетчер управления, принимает на вход только 3 программы, но многократно. то есть сначала вся очередь состоит из первой программо, когда данная программа выполнилась, она удаляется из очереди и в очередь добавляется вторая програма на выполнение и тд. это программы которые я тоже должен написать сам(точнее уже написал) - простые программы, в которых есть немножко кода записаного в int main(). вот так то.
или даже в этом слчае фраза
Цитата:
Сообщение от waleri Посмотреть сообщение
"100% решения вашей проблемы нет"
остается в силе?

Последний раз редактировалось lowercase; 08.10.2012 в 13:37.
lowercase вне форума Ответить с цитированием
Старый 08.10.2012, 13:40   #5
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Цитата:
я пробовал так:
так а что не работает-то? из того куска кода, что у вас, можно только увидеть, что вы даёте процессу 10 мс, потом замораживаете его главный поток... и всё. Где происходит размораживание, и в чём вобще проблема, так и не ясно.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 08.10.2012, 13:49   #6
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

Цитата:
Сообщение от veniside Посмотреть сообщение
и в чём вобще проблема, так и не ясно.
извените за столь большую кучу текста и минимума сути.

вот так у меня выглядит main();
Код:
int main(int ac, char* av[]){
	const int n = ac > 1 ? atoi(av[1]) : 30;
	char* cmdline = (char*)calloc(64, sizeof(char));
	unsigned int i, filename = 0;
	PID pid;

	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	queue cp = create_queue(); // создаю пустую очередь 

	for(i = 0; i < n; i++){
		ZeroMemory(&si, sizeof(STARTUPINFO));
		cmdline = make_cmdline(i, MAKE);
		CreateProcess(NULL, cmdline, NULL, NULL,
			FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
		add_queue(&cp, pi, MAKE, i); // добавляю "спящий" процес в очередь выполенения
		printf("added to queue process \"%s\"\n", cmdline);
	}
	while(cp.begin){ // пока в очереди есть хотябы один процес на выполнение
		pi = select_proc_queue(&cp, &pid, &filename);
		ResumeThread(pi.hThread); // возобновляю выполнение
		int call_result = WaitForSingleObject(pi.hProcess, MAXT_PROCESS_TIME);
		if(call_result == WAIT_OBJECT_0){
			// значит процес выполнился(но я не уверен в правильности,
			// ибо 10 мс может и не хватить на выполнение)
			if((pid = next_pid(pid)) != NOPID){
				
				ZeroMemory(&si, sizeof(STARTUPINFO));
				cmdline = make_cmdline(filename, pid);
				CreateProcess(NULL, cmdline, NULL, NULL,
					FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
				add_queue(&cp, pi, pid, filename);
			}
			delete_first(&cp); // если процес выполнился удаляю его их очереди
			cmdline = make_cmdline(cp.begin->filename, cp.begin->pid);

			printf("process %s was end with code %d\n", cmdline, call_result);
			printf("procees %s was deleted from queue\n", cmdline);
		} else {
			// значит процес не выполнился. приостанавливаю его поток
			SuspendThread(pi.hThread);
			cmdline = make_cmdline(cp.begin->filename, cp.begin->pid);
			printf("moving process %s to end of queue\n");
			move_first_to_end(&cp);
		}
	}

	free(cmdline);
	getch();
	return 0;
}
проблема в том когда выполняю эту программу, то вызываемые в очереди процесы не выполняются до конца, соотвественно и главная програма ждет их завершения, и ничего, кроме как завершить работу через диспетчер задач windows, сделать нельзя . я полагаю, что программа неправильно рабоатает иза этих строчек:
Код:
 int call_result = WaitForSingleObject(pi.hProcess, MAX_PROCESS_TIME);
 if(call_result == WAIT_OBJECT_0)

Последний раз редактировалось lowercase; 08.10.2012 в 13:57.
lowercase вне форума Ответить с цитированием
Старый 08.10.2012, 13:59   #7
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Отпечатайте что содержит pi.hThread перед каждым вызовом SuspendThread/ResumeThread а также проверяйте вызовы на предмет ошибок.

Кроме того, не совсем понятно зачем надо создавать оконченные процессы заново? Именно поэтому ваш цикл никогда не заканчивается.
Кстати, кто будет закрывать ненужные HANDLE?

PS.
Еслки процессы точно однопоточные, тогда в принципе проблем не должно быть, но опять таки, если процесс сам сделает себе ResumeThread лишний раз, тогда у вас уже не получится останавливать поток.
waleri вне форума Ответить с цитированием
Старый 08.10.2012, 14:06   #8
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

нет, нет, цыкл не заканичваются потому, что програмы программы не выполняются. то есть до строчки printf("process %s was end with code %d\n", cmdline, call_result); дело не доходит.
и там не одни и теже программы создаются заново. там разные. всего три программы, которые выполняются в строго определенном проядке. вот эти строчки
Код:
 if((pid = next_pid(pid)) != NOPID)
...
cmdline = make_cmdline(filename, pid)
и определяет какой из них будет дальше выполнятся. а когда уже выполнена 3я программа то в очередь ничего не добавляется, и очередь стает меньшей на 1 програму.

Последний раз редактировалось lowercase; 08.10.2012 в 14:14.
lowercase вне форума Ответить с цитированием
Старый 08.10.2012, 14:12   #9
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

попробовал выводить pi.hThread, вставил строчки для вывода перед ResumTheard(pi.hThread) и SuspendTheard(pi.hThread);
программа выводит только для первого процеса, дальше стандартное окно ошибки приложения windows, а программа ожидает завершения созданых ею процесов.
lowercase вне форума Ответить с цитированием
Старый 08.10.2012, 14:17   #10
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

эм. может тогда мне надо проверять на WAIT_TIMEOUT, а не на WAIT_OBJECT_0?
lowercase вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Приостановка выполнения цикла ACE Valery Общие вопросы C/C++ 21 19.11.2011 12:40
многократная выгрузка запроса по парамеру в excel omka Microsoft Office Access 0 23.05.2011 18:31
Многократная декларация Greynvi4 Общие вопросы C/C++ 17 10.08.2009 16:52
приостановка выполнения процедуры BESS Общие вопросы Delphi 5 15.09.2008 00:53
Приостановка цикла для выполнения внешней программы Uomo Общие вопросы Delphi 3 04.04.2008 11:48