LINUX.ORG.RU

Как узнать pid процессов-братьев?


0

0

Пишу лабораторную работу. По заданию нужно создать дерево процессов(через fork), а потом по заданной последовательности процессы должны обмениваться сигналами. Проблема состоит в том, как процессу узнать pid процесса, который является, например, его братом(дедом)? Я думаю сделать так: головной процесс составляет массив из pid'ов при создании дерева процессов, а после создания этого дерева передает через этот массив через канал всем своим детям, внукам и правнукам. Но как-то тут не очень красиво получается. Может быть есть вариант получше?

для братьев будет выполняться ppid == ppid. вызов вроде getppid(), возвращает пид родительского процесса.

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

gunja
()
Ответ на: комментарий от gunja

В задании каждый процесс пронумерован и дана последовательность отправки сигналов по этим номерам. Может быть такое, что сообщение отправляется и дяде(т.е. брату родителя), и прадеду и вообще кому угодно. И при этом дерево очень разветвленное. Вот передо мной и стоит задача, как процессу узнать pid, своего дяди, которому надо отправить сигнал.

miksayer
() автор топика

Хранить в shared memory все дерево процессов можно. Когда процесс1 запускает новый процесс2, он добавляет процесс2 в дерево. Все через мьютексы конечно.

winlogon
()
Ответ на: комментарий от winlogon

А где можно почитать про мьютексы и shared memory? чтоб крактко и понятно было :-) просто только начал изучать программирование под *nix... И может быть есть более красивый способ построения дерева процессов, чем «дерево» из конструкций if-else, проверяющих значения, возвращаемые fork'ом?

miksayer
() автор топика
Ответ на: комментарий от miksayer

А где можно почитать про мьютексы и shared memory?


Стивенс. UNIX:взаимодействие процессов

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от miksayer

немного полазил по гуглу. Как я понимаю мьютексы мне тут понадобяться только для того, чтобы запретить процессам выполняться до тех пор, пока полностью не будет построено и записано в shared memory дерево процессов?

miksayer
() автор топика
Ответ на: комментарий от miksayer

Не знаю сложность вашей задачи, но по идее в шаренную память может понадобиться запись всем процессам, ведь дедушка должен узнать pid'ы внуков.

А относительно дерева if-else. Наверное вам нужно для каждого процесса ввести некий идентификатор 1, 2, и т.д., потом записать для каждого процесса (по идентификатору) сколько раз ему делать fork и какие идентификаторы передавать потомкам.

То есть делаем массив из пар чисел, id и id потомка. Каждый процесс знает свой id, он выставляется в некоторую переменную родителем перед форком. Каждый процесс один раз просматривает весь массив и для каждого найденного своего id делает fork(), указывая потомку какой у него id.

Возможно, что эти id уже введены в задаче, иначе как там описывается какой процесс какому должен отправлять сигнал.

mky ★★★★★
()
Ответ на: комментарий от miksayer

>>немного полазил по гуглу. Как я понимаю мьютексы мне тут понадобяться только для того, чтобы запретить процессам выполняться до тех пор, пока полностью не будет построено и записано в shared memory дерево процессов?

Мьютекс (точнее, семафор) тебе будет нужен, потому что shm - разделяемый ресурс, одновременный доступ к нему на чтение/запись грозит проблемами.

MuZHiK-2 ★★★★
()
Ответ на: комментарий от placement_new

>>А разместить в shm мьютекс заменит семафор? лок и анлок атомарны ж.

Во-первых, мьютекс - частный случай семафора. Во-вторых, не понял, что ты и где хочешь разместить. И да, лок и анлок атомарны.

MuZHiK-2 ★★★★
()
Ответ на: комментарий от MuZHiK-2

В разделяемой памяти создать мьютекс и использовать его для доступа к этому дереву pidов. Интерфейс мьютекса все ж попроще будет, чем ipc semaphore. Можно так?

placement_new ★★
()

Если все ваши процессы имеют одинаковые имена, возможно, вам пригодится функция, которую я писал для «убивания» одноименных процессов (чтобы гарантировать, что запущенный нами процесс - единственный, кто имеет доступ к железяке):

#include "killbrothers.h"
#define PROC_BASE "/proc"

void readname(char *name, pid_t pid){ // считать имя процесса из /proc/...
	char *pp = name, byte, path[256];
	int cntr = 0, file;
	sprintf (path, PROC_BASE "/%d/cmdline", pid);
	file = open(path, O_RDONLY);
	do{	// считываем имя без слешей
		read(file, &byte, 1);
		if (byte != '/') *pp++ = byte;
		else pp = name;
	}
	while(byte != EOF && byte != 0 && cntr++ < 255);
	close(file);
}

void killbrothers(){
	DIR *dir;
	struct dirent *de;
	pid_t pid, self;
	char name[256], myname[256];
	if (!(dir = opendir (PROC_BASE))){ // открываем директорию /proc
		perror (PROC_BASE);
		exit (1);
	}
	self = getpid(); // свой идентификатор
	readname(myname, self); // свое имя процесса
	while ((de = readdir (dir)) != NULL){ // пока не дойдем до конца директории
	// пропустим, если директория не указывает на процесс, или указывает на self
		if (!(pid = (pid_t) atoi (de->d_name)) || pid == self)
			continue;
		readname(name, pid); // считываем имя процесса
		if(strncmp(name, myname, 255) == 0){ // если оно совпадает с self
			#ifdef __TEST__
			fprintf(stderr, "Found running process...\nKilling\n");
			#endif
			kill(pid, 9); // убиваем без разговоров
			sleep(3); // подождем, пока процесс не умрет окончательно
		}
	}
	closedir(dir);
}
killbrothers.h:
#ifndef KILLBROTHERS_H
#define KILLBROTHERS_H
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
#include <pwd.h>
#include "iftest.h"
void killbrothers();
#endif // KILLBROTHERS_H
Вместо
kill(pid, 9);
sleep(3);
просто генерируйте массив pid'ов и возвращайте его.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от placement_new

>>В разделяемой памяти создать мьютекс и использовать его для доступа к этому дереву pidов. Интерфейс мьютекса все ж попроще будет, чем ipc semaphore. Можно так?

Не понимаю, нафига козе баян? В чем трудность с получением семафора посредством ftok и semget? В теории - да, где-то ты должен проинитить мьютекс и сохранить его в память. Но это решение больше подвержено проблемам, если кто-то из процессов запишет в эту область памяти. Да, мьютексы немного быстрее работают, но нужно ли оно? Мьютексы лучше подходят для потоков.

MuZHiK-2 ★★★★
()
Ответ на: комментарий от MuZHiK-2

Да, я еще прикинул, а как ты будешь этот мьютекс считывать и сохранять? Данные в памяти обычно выравниваются компилятором, поэтому просто считать из разделяемой памяти в переменную может не прокатить. Надо будет использовать что-то типа __packed__.

MuZHiK-2 ★★★★
()
Ответ на: комментарий от placement_new

>>Почему не прокатит? компилятор то один. PTHREAD_PROCESS_SHARED для этого и есть ж.

Если компилятор один - то да, прокатит. Но если позже понадобится расширить задачу на взаимодействие процессов не родственных, то ты поимеешь смачный гемор. Пойми, что ты сейчас страдаешь настоящим маразмом: пытаешься прикрутить межпотоковое взаимодействие (мьютексы) к межпроцессному. О том, какие костыли появляются - думаю, рассказывать не надо больше.

MuZHiK-2 ★★★★
()
Ответ на: комментарий от MuZHiK-2

Ну и в догонку представь ситуацию: процесс, который у тебя держит мьютекс, сегфолтится и что? Все остальные остаются в дедлоке?

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