// Листинг 13.8. Использование функции posix_spawn() для
// запуска источников знаний
#include blackboard::blackboard(void) {
//.. .
pid_t Pid;
posix_spawnattr_t M;
posix_spawn_file_actions_t N;
posix_spawn_attr_init(&M);
posix_spawn_file_actions_init(&N);
char *const argv[] = {«knowledge_source1»,NULL};
posix_spawn(&Pid,«knowledge_source1»,&N,&M,argv,NULL);
//. . .
}
В листинге 13.8 инициализируются атрибуты и действия, необходимые для порождения задач, после чего с помощью функции posix_spawn() создается отдельный процесс, который предназначен для выполнения источника знаний knowledge_source1. После создания этого процесса «классная доска» получает к нему доступ через его идентификационный номер, сохраняемый в параметре Pid.Кроме «классной доски», используемой в качестве средства связи, возможно и стандартное межпроцессное взаимодействие (IPC), если «классная доска» расположена на одном компьютере с источниками знаний. «Классная доска» — самый простой способ взаимодействия между источниками знаний, хотя в конфигурации размещения «классной доски» на отдельном компьютере можно использовать с этой целью сокеты. В этом случае управление, осуществляемое «классной доской» над источниками знаний, будет более жестким и обусловленным в любой момент времени содержимым «классной доски», а не сообщениями, передаваемыми непосредственно источникам знаний. Прямую пересылку сообщений легче реализовать при использовании «классной доски» в сочетании с PVM-задачами. В этом случае источники знаний сами настраивают себя на основе содержимого «классной доски». Но «классная доска» все же имеет определенный «рычаг»управления источниками знаний, поскольку ей «известны» идентификационные номера всех процессов, содержащих источники знаний. Как модель MPMD (MIMD), так и модель SPMD (SIMD), также поддерживаются использованием функции posix_spawn().В листинге 13.9 представлен класс, который можно использовать в качестве объекта-функции при выполнении алгоритма for_each ().
// Листинг 13.9. Использование класса child_process как
// объекта-функции при запуске источников
// знаний
class child_process{
string Command;
posix_spawnattr_t M;
posix_spawn_file_actions_t N;
pid_t Pid;
//.. .
public:
child_process(void);
void operator()(string X);
void spawn(string X);
};
void child_process::operator()(string X) {
//.. .
posix_spawnattr_init(&M);
posix_spawn_file_actions_init(&N);
Command.append("/tmp/");
Command.append(X);
char *const argv[] = {const_cast(Command.data()),NULL};
posix_spawn(&Pid,Command.data(),&N,&M,argv,NULL);
Command.erase(Command.begin(), Command.end()); //.. .
}
Мы инкапсулируем атрибуты, необходимые для функции posix_spawn(), в классе child_process.Инкапсуляция всех данных, требуемых для вызова этой функции в классе, упро щ ает ее использование и обеспечивает естественный интерфейс с атрибутами процесса, который создается с ее помощью. Обратите внимание на то, что в классе child_processмы определили функцию operator() (см. листинг 13.9). Это означает, что класс child_processможно использовать в качестве функционального объекта при выполнении алгоритма for__each(). По мере того как «классная доска» решает, какие источники знаний необходимо активизировать для решения задачи, она сохраняет их имена в контейнере Solve.Позже при выполнении конструктора «классной доски» нужные источники знаний активизируются с помощью алгоритма for_each ().
// Конструктор.
//...
child_process Task;
for_each(Solve.begin(), Solve.end(), Task);
При выполнении этого конструктора для каждого элемента контейнера Solveвызывается метод operator(), код которого приведен в листинге 13.9. После активизации источники знаний получают доступ к ссылке на объект «классной доски» и могут приступать к решению свой части задачи. И хотя источники знаний здесь не являются PVM-задачами, они связываются с «классной доской» таким же способом (см. подраздел 13.5.3.2) и так же выполняют свою работу. Дело в том, что межпроцессное взаимодействие между стандартными UNIX/Linux-процессами отличается от межпроцессного взаимодействия, которое возможно с использованием PVM-среды. Кроме того, PVM-задачи могут располагаться на разных компьютерах, в то время как процессы, созданные с помощью функции posix_spawn(), могут существовать только на одном и том же компьютере. Если процессы, созданные функцией posix_spawn() (либо семейством функций fork-exec), необходимо использовать в сочетании с моделью SIMD, то в дополнение к объекту «классной доски» для назначения источникам знаний конкретных областей задачи, которые они должны решать, можно использовать параметры argc и argv. В случае, когда «классная доска» находится на одном компьютере с источниками знаний, и она активизирует источники знаний в своем конструкторе, то формально «классная доска» является для них родителем, а потомки наследуют от родителя переменные среды. Переменные среды «классной доски» можно использовать в качестве еще одного способа передачи информации источникам знаний. Этими переменными среды можно легко управлять, используя следующие функции.
Читать дальше