Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> завершение родительского процесса из дочернего, завершение родительского процесса из доч 
V
    Опции темы
ihtiandr
  Дата 15.7.2011, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 16.12.2010

Репутация: нет
Всего: нет



Всем доброго времени суток.
Мне нужно из дочернего процесса закрыть родительский, но ничего не выходит.
Вот исходник дочернего
Код

#include<windows.h>
#include<conio.h>

int main(int argc, char *argv[])
{
char c;
HANDLE hThread;

hThread =  (HANDLE)atoi(argv[1]);

while (true)
  {
   cputs("Input 't' to terminate the thread: ");
   c =_getch();
   if (c=='t')
     {
      cputs("t\n");
      break;
     }
    TerminateThread(hThread,0);
    CloseHandle(hThread);
    cputs("Pres any key to exit.\n");
    _getch();
    return 0;
  }
}


Вот родительского
Код


#include<windows.h>
#include<conio.h>
volatile int count;

void thread()
{
for(;;)
{
count++;
Sleep(500);
cprintf("count= %d\n",count);
}
}

int main()
{
char lpszComLine[80];
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;

HANDLE hThread;
DWORD IDThread;

sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = True;

hThread = CreateThread(&sa,0,(LPTHREAD_START_ROUTINE)thread, NULL, 0, &IDThread);

if(hThread == NULL)
return GetLastError();

ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);

wsprintf(lpszComLine,"c:\\CP.exe %d",(int)hThread);

if(!CreateProcess(
NULL,
lpszComLine,
NULL,NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi))
{
cputs("The new process is't created");
_getch();
return GetLastError();
}

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

WaitForSingleObject(hThread,INFINITE);
        cputs("Press any key to exit");
        _getch();
CloseHandle(hThread);
return 0;


}



Когда запускаю родительский процесс он запускает дочерний а в дочернем при нажатии на "t" сам себя закрывает а родительский продолжает работать.
Помогите разобраться. 
PM MAIL   Вверх
YDean
Дата 15.7.2011, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 7.9.2009

Репутация: 1
Всего: 1



Значение, возвращаемое функцией CreateThread, валидно только в контексте вызывающего ее процесса.
Для передачи описателей(handles) между процессами нужно использовать DuplicateHandle.

В данном примере нужно передать описатель потока, а также реальный описатель процесса. 
Чтоб в том процессе по ним восстановили правильный описатель потока.

Поскольку GetCurrentProcess() возвращает псевдоописатель текущего процесса, перед отправкой его нужно преобразовать в реальный через
DuplicateHandle(GetCurrentProcess(),GetCurrentProcess(),GetCurrentProcess(), &hRealProcess, 0,0 1,DUPLICATE_SAME_ACCESS)


Хотя, TerminateThread использовать нехорошо. Он не освобождает стек потока.
(еще могут быть проблемы с правами на разных виндах)
Лучше передавать mutex. 
Или не передавать, а создавать и открывать именованный mutex/event.

Это сообщение отредактировал(а) YDean - 18.7.2011, 22:44
PM   Вверх
ihtiandr
Дата 16.7.2011, 06:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 16.12.2010

Репутация: нет
Всего: нет



YDean
Я изменил родительский процесс используя DuplicateHandle
Вот код:

Код

#include<windows.h>
#include<conio.h>
volatile int count;

void thread()
{
for(;;)
{
count++;
Sleep(500);
cprintf("count= %d\n",count);
}
}

int main()
{
char lpszComLine[80];
char lpszHandle[20];
STARTUPINFO si;
PROCESS_INFORMATION pi;

HANDLE hThread, hInheritThread;
DWORD IDThread;



hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread, NULL, 0, &IDThread);
wsprintf(lpszComLine,"c:\\CP.exe %d",(int)hThread);

if(!DuplicateHandle(GetCurrentProcess(),
hThread,
GetCurrentProcess(),&hInheritThread,
 0,TRUE,DUPLICATE_SAME_ACCESS))

ZeroMemory(&si,sizeof(STARTUPINFO));
 si.cb = sizeof(STARTUPINFO);
 itoa((int)hInheritThread,lpszHandle,10);
 strcat(lpszComLine,lpszHandle);

if(!CreateProcess(
NULL,
lpszComLine,
NULL,NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi))

{
cputs("The new process is't created");
_getch();
return GetLastError();
}

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
_getch();

CloseHandle(hThread);
return 0;

}


Теперь у меня при запуске родительского процесса дочернимй вообще не выходит а монитор становится красным и выходит ошибка"Ошибка при инициализации приложения 0хс0000005" при нажатии на "Ок" родительский процесс не завершается а продолжается.
PM MAIL   Вверх
ASMatic
Дата 16.7.2011, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 14.3.2009

Репутация: 1
Всего: 1



ihtiandr, правильней не убивать процесс,а оповещать его что пора ему завершится.
Уже подсказывали как
http://msdn.microsoft.com/en-us/library/ms...6(v=VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms...1(v=VS.85).aspx
создаем, указываем нейм. Открываем.
WaitForSingleObject(), можно заюзать с таймаутом и время от времени в треде проверять.

*а с кодом что вашим - почему бы под отладчиком не посмотреть на какой инструкции получаем #AV
PM MAIL   Вверх
YDean
Дата 16.7.2011, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 7.9.2009

Репутация: 1
Всего: 1



ihtiandr, опять неверно
DuplicateHandle  преобразует описатели между процессами.
Поскольку при формировании строки запуска дочерний процесс еще не существует - то и преобразовать к нему мы не сможем. 
Это он должен сделать сам.
Для этого ему нужен реальный описатель родительского процесса.


И ASMatic дело говорит. 
Я именно это и пытался сказать выше после "Хотя...".
PM   Вверх
bass
Дата 16.7.2011, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 5.8.2007

Репутация: 2
Всего: 2



Ребят дубликате хандле конечно круто, но задача вообще банальна..........

Если приложение (родитель)GDI....... то передаем дескриптор главного окна HWND ....... Процес (ребенок) постмессаге вм_клосе.....
Приношу извинения за написание на русском языке..........................

Консольное приложение процесс родитель передает дочерниму  IdProcees GetCurrentProcessId .............     Дочерний процесс OpenProcess Terminate.........

Корректно процесс родитель запускает процесс дочерний и остается ждать евента ...... Пришел евент exit(0);
PM MAIL   Вверх
Estranged
Дата 16.7.2011, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: 3
Всего: 3



YDean, DuplicateHandle в таком виде не подойдет. А HANDLE он может передать, потому что sa.bInheritHandle = TRUE;. Дочерний процесс может использовать его.

Ошибка не давала этому чуду работать:
Код

while (true)
  {
   cputs("Input 't' to terminate the thread: ");
   c =_getch();
   if (c=='t')
     {
      cputs("t\n");
      break; <---------------- TerminateThread(hThread,0); не выполнялся просто
     }


Добавлено через 5 минут и 58 секунд
И еще у родительского заменить void thread() на DWORD WINAPI thread(LPVOID)
PM MAIL   Вверх
YDean
Дата 17.7.2011, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 7.9.2009

Репутация: 1
Всего: 1



Смешно.  smile 
Estranged, +1
Цитата
DuplicateHandle в таком виде не подойдет.
Всю жизнь работало. 
Jeffrey Richter ошибается? smile
Цитата
А HANDLE он может передать, потому что sa.bInheritHandle = TRUE;. Дочерний процесс может использовать его.
Это правда. Недосмотрел.

PM   Вверх
Estranged
Дата 17.7.2011, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: 3
Всего: 3



YDean, DuplicateHandle(GetCurrentProcess(),GetCurrentProcess(),GetCurrentProcess(), &hRealProcess, 0,0,DUPLICATE_SAME_ACCESS)

Да Рихтер прав, в MSDN написано все, о чем Рихтер не сказал явно, только намекал.

Внимание, вопрос: для какого процесса приведенный пример создает дубликат HANDLE текущего процесса?
PM MAIL   Вверх
YDean
Дата 18.7.2011, 22:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 7.9.2009

Репутация: 1
Всего: 1



Да, да, да. Всё понятно.  smile 
bInheritHandle=1
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0772 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.