LINUX.ORG.RU

C: fork, exec*, system и прочие...


0

0
Пишу программу на C. Нужна функция, которая запускает внешнюю программу. Но или память всей программы + дескрипторы открытых файлов копируются посредством fork+execlp, или после выполнения vfork+execlp в системе остаются запущенные программы, которые в ps отображаются со словом <defunct>.

Поэтому прошу помощи в запуске внешних приложений или какое-нибудь руководство по exec* + (v)fork, отличное от MAN'ов.


вы используете где-нибудь wait ?
help_us
()
Это называется zombie. Умерший дочерний процесс ожидает, когда родитель обратит на него внимание. Обращать внимаение, как уже написали, нужно функцией wait. Вообще, в любой, даже самой базовой книжке по программированию в UNIX об этом написано.
mv ★★★★★
()
Ответ на: комментарий от mv
wait нигде не использую. Про zombie и wait еще попробую покопать, ибо, как начинающий программист, до зомби я еще не добрался))

Про KDE тоже почитаю, но, думаю, мне это вряд ли поможет, потому что тащить за собой зависимости kde в программе, которая непосредственно завсит только от libc+kernel, - это нехорошо))

DiGital
() автор топика
Ответ на: комментарий от DiGital
KDE там сбоку припёку, класс KProcess служит для запуска процессов и написан на 90% на классическом fork()+exec()+коммуникации. Тебе там будет интересно посмотреть как запускаются процессы с флагом DontCare (что значит не ждать завершения дочернего процесса и не привязываеть его в объекту KProcess'a). Собственно, нечего страшного не будет, если ребёнок завершится раньше родителя без wait()-а.
alex_custov ★★★★★
()
Ответ на: комментарий от DiGital
Вроде бы сделал. Зомби не появляются, но осталось несколько вопросов:
1) Нужно ли как-ниубдь обрабатывать status?
2) Что лучше: оставить vfork() или заменить на fork()? Как раз в том листинге с сайта kde используют fork:
" // we don't use vfork() because
  // - it has unclear semantics and is not standardized"
3) Сомнения по поводу execlp и способа запуска программ. Нету ли тут подводных камней?

Чем мне и системе грозит каждый из вариантов?

Привожу кусок из программы. Здесь data - массив из структур, поле command которых содержит имя запускаемой программы с параметрами,
передаваемыми ей.

int
run_command (int cmdcode)
{
	int status;
	if (data[cmdcode].command == NULL)
		return 0;

	switch (vfork())
	{
		case 0:
			setsid();
			execlp ("sh", "sh", "-c", data[cmdcode].command, (char *) NULL);
			_exit(0);
			break;
		case -1:
			fprintf(stderr, "%s: Error in vfork()\n", procname);
			break;
		default:
			wait(&status);
	}
	return 0;
}
DiGital
() автор топика
Ответ на: комментарий от alex_custov
>как запускаются процессы с флагом DontCare

Спасибо. Именно это мне и было интересно. Разберусь и, может, перепишу ф-цию. :-)

DiGital
() автор топика
Вообщем варианты:

1. В родительском процессе сразу после fork делать wait - но таким образом мы лочим родительский процесс до завершения дочернего.

2. Обрабатывать в родительском процессе сигналы и по событию смерти вызывать wait.

3. Делать double fork: http://www-h.eng.cam.ac.uk/help/tpl/unix/fork.html

anonymous
()
Ответ на: комментарий от DiGital
1. это результат завершения вызываемой программы - согласно логике программы
2. когда я написал fork в своей программе я с удивлением обнаружил, что gcc заменил его на vfork =)
3. в данном конкретном случае наверно лучше будет использовать system
generatorglukoff ★★
()
Ответ на: комментарий от DiGital
если хочешь, чтоб работало под любым *nix'ом, то используй fork
Reset ★★★★★
()
Ответ на: комментарий от DiGital
>switch (vfork())

Вместо vfork, используй fork. На сегодняшний день vfork не выполняет свое дело быстрее, чем fork, однако, его использование сопряжено с некоторым риском.

Demon37 ★★★★
()
Ответ на: комментарий от Demon37
Всем огромное спасибо за помощь! Пока устроил вариант с двойным fork()'м. В дальнейшем буду копать в сторону KProcess.
DiGital
() автор топика
Ответ на: комментарий от Demon37
> На сегодняшний день vfork не выполняет свое дело быстрее, чем fork

Еще как быстрее, особенно на толстых процессах! Довольно дорогая операция в fork -- пройтись по всем страницам и пометить их грязными -- в vfork отсутствует.

Die-Hard ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.