2009-04-28 3 views
0

Я разрабатываю программу на C++, которая имеет метод «сканирования», который будет запускать относительно длительную процедуру сканирования. Когда процедура будет завершена, метод сканирования уведомит наблюдателей о результатах с использованием шаблона наблюдателя.Резьбовая реализация шаблона наблюдателя - C++

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

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

#include <boost/thread/thread.hpp> 
#include <boost/thread/mutex.hpp> 
#include <boost/bind.hpp> 
#include <iostream> 

boost::mutex io_mutex; 

void scan(int scan_target, vector<Listener> listeners) 
{ 
    //...run scan 
    { 
    boost::mutex::scoped_lock 
     lock(io_mutex); 
    std::cout << "finished scan" << endl; 
    // notify listeners by iterating through the vector 
    // and calling "notify() 

    } 
} 

int main(int argc, char* argv[]) 
{ 

    vector<Listener> listeners 
    // create 
    boost::thread thrd1(
    boost::bind(&scan, 1, listeners)); 
    boost::thread thrd2(
    boost::bind(&scan, 2, listeners)); 
    //thrd1.join(); 
    //thrd2.join(); 
    return 0; 
} 

ли это выглядеть примерно правильно? Нужно ли мне mutex-вызов для прослушивания? Можно ли избавиться от объединений?

+0

Что вы пытаетесь защитить с помощью мьютекса? Список слушателей? Вы пытаетесь предотвратить перекрытие итераций через список? – DanM

ответ

0

Я не знаю, что такое форсированный материал, но концептуально он выглядит правильно. У вас есть наблюдатели, которые хотят получать уведомления о государственных изменениях. Когда происходит «квалифицируемое событие», вам необходимо пропустить список (или вектор, что-то подобное) Наблюдателей для уведомления. Вы также хотите, чтобы убедиться, что-то, что параллельные уведомления не причинить вам неприятности,

(Вот Wikipedia articl е по образцу.)

1

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

0

Прослушиватель :: Notify() вызывается из нескольких потоков, так что если Notify() не имеет побочных эффектов, вы должны будете сделать одно из трех:

  1. Внешний замок (ваш пример): получение мьютекса перед вызовом Слушатель :: Notify()
  2. Внутренний замок: Слушатель :: Notify() будет получить блокировку внутри
  3. Блокировка бесплатно: поиск «заблокировать свободный алгоритм» в гугле

Есть про s/cons для каждого варианта ...

Для чего (я думаю) вам нужен вариант 1 будет хорошим.

И вам придется оставить заявления о присоединении, иначе ваш main() может выйти, прежде чем ваши потоки смогут закончить работу. Также рассмотрите использование boost::thread_pool и joint_all.

Смежные вопросы