Порождение источников знаний с помощью PVM-задач
Конструктор «классной доски» содержит следующий вызов алгоритма, for_each(Solve.begin(),Solve.end(), Task);
Алгоритм for_each () применяет операторный метод объекта функции (созданного для класса задачи) к каждому элементу контейнера Solve. Этот метод используется для порождения источников знаний в соответствии с моделью MIMD, при реализации которой все источники знаний имеют различную специализацию и работают с различными наборами данных. Объявление этого класса задач приведено в листинге 13.4.
>// Листинг 13.4. Объявление класса задачи
>class task{
>int Tid[4];
>int N;
>//. . .
>public:
>//. . .
>task(void) { N = 0; } void operator()(string X);
>};
>void task::operator()(string X) {
>int cc; pvm_mytid();
>cc = pvm_spawn(const_cast(X.data()),NULL,0,"",l,&Tid[N]);
>N++;
>}
>blackboard::blackboard(void) {
>task Task;
>vector Solve;
>//.. .
>// Determine which KS to invoke
>//. . .
>Solve.push_back(KS1);
>Solve.push_back(KS2);
>Solve.push_back(KS3);
>Solve.push_back(KS4);
>for_each(Solve.begin(), Solve.end(), Task);
>}
Этот класс task инкапсулирует порожденный процесс. Он содержит идентификационный но м ер задачи (поскольку у нас используется PVM-задача). В случае при м енения стандартных UNDC/Linux-процессов или Pthread-потоков, он должен содержать идентификационный но м ер процесса или потока. Этот класс действует как интерфейс между создаваемым процессом или потоком и «классной доской». «Классная доска» здесь является основным компонентом управления. Она может управлять PVM-задачами с помощью их идентификационных номеров. Кроме того, «классная доска» может использовать групповые PVM-операции для синхронизации PVM-задач с использованием барьеров, организации PVM-задач в логические группы, которые должны отрабатывать определенные аспекты решаемой задачи, и сигнализации членов группы с помощью соответствующих тегов сообщений. Групповые PVM-операции перечислены и описаны в табл. 13.2.