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 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.