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

>blackboard::blackboard(void) {

>pthread_t Tid[4];

>//.. .

>try{

>pthread_create(&Tid[0],NULL,suggestionForMajor, NULL);

>pthread_create(&Tid[l],NULL, suggestionForMinor, NULL);

>pthread_create(&Tid[2], NULL,suggestionForGeneral, NULL);

>pthread_create(&Tid[3],NULL, suggestionForElective, NULL);

>pthread_join(Tid[0],NULL);

>pthread_join(Tid[l],NULL);

>pthread_join(Tid[2],NULL);

>pthread_join(Tid[3],NULL);

>}

>//. . .

>}

Обратите внимание на то, что конструктор вызывает функцию pthread_join(). Этот вызов заставляет конструктор ожидать завершения работы всех четырех потоков. Эти потоки могут активизироваться и с помощью других функций-членов класса blackboard. Но те действия, которые выполняют источники знаний «в рамках» конструктора, представляют своего рода предварительную инициализацию «классной доски», поэтому весьма уместно не продолжать работу по созданию объекта «классной доски» до тех пор, пока эти потоки не доведут до конца свою работу. Такой подход к созданию потоков в конструкторе заставляет задуматься об обработке ошибок и исключительных ситуаций. Что произойдет, если по какой-то причине при выполнении потоков случится сбой? Поскольку конструкторы не возвращают никаких значений, то здесь просто необходимо позаботиться об обработке исключительных ситуаций. Каждый поток связывается со «своей» функцией.

>void   *suggestionForMajor(void *X);

>void   *suggescionForMinor(void *X);

>void   *suggestionForGeneral(void *X);

>void   *suggestionForElective(void *X);

Эти четыре функции используются потоками для реализации действий соответствующих источников знаний. Поскольку «классная доска» является глобальным объектом, каждая из этих функций имеет непосредственный доступ к функциям-членам класса blackboard. Поэтому источники знаний могут вызывать функции-члены «классной доски» напрямую.

>//...

>Combination.generateCombinations(1,9, Courses);

>Result = Combination.element(9);

>//.. .

>Blackboard.suggestionsForMinor(Value);

>//.. .

Поскольку некоторые разделы «классной доски» имеют ограниченный доступ для отдельных источников знаний, то к этим разделам можно применить CRCW-стратегию доступа (рис. 13.9).

Тип параллелизма, представленный на рис. 13.9, вполне естествен для систем, реализующих модель «классной доски», поскольку «классная доска» часто делится на разделы, относящиеся к определенным частям задачи или подзадачи. Обычно одной проблемной области соответствует один источник знаний, поэтому параллельный доступ к этим разделам вполне уместен.

Резюме

Рис. 13.9. Четыре источника знаний могут параллельно считывать информацию из соответствующих разделов «классной доски» и записывать ее туда