Параллельное и распределенное программирование на С++ (Хьюз, Хьюз) - страница 352

о при м еняют сов м естно со стандартны м и алгорит м а м и в м есто функций и л и в допо л нение к ни м. Обычно везде, где м ожно использовать обычную функцию, ее м ожно за м енить объекто м -функцией. Чтобы определить собственный функциональный объект, необходи м о определить операторный м етод operator (), придав е м у соответствующий с м ысл, указав список пара м етров и тип возвращае м ого и м значения. Наша CORBA-реализация «классной доски» м ожет под д ерживать источники знаний, реализованные с по м ощью PVM-задач, традиционных UNDC/Linux-задач или от д ельных потоков, использующих библиотеки POSIX thread. По типу задач, порождае м ых в конструкторе, м ожно определить, с каки м и и м енно задача м и будет работать «классная доска»: с POSIX-потока м и, традиционны м и UNIX/Linux-процесса м и или PVM-задача м и.

Порождение источников знаний с помощью 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.