Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ boost _ boost::interprocess

Автор: alexy 23.2.2013, 0:23

Создаю я значит класс, который можно вызывать из разных процессов, типа

using namespace boost::interprocess;

class foo {
public:
  std::string bar()const{
     shared_lock<interprocess_upgradable_mutex> lock(mutex);
     // get the data;
     return data;
   }
  void bar(const std::string& nb){
     scoped_lock<interprocess_upgradable_mutex> lock(mutex);
     //write the data
  }

private:
  static interprocess_upgradable_mutex mutex;
};
// определяю mutex в cpp файле


У меня вываливается (еще до вызова конструктра, даже заблокировать-то еще не успел ничего)
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::lock_error> >'
  what():  boost::lock_error


Может я не правильно библиотеку использую?

Автор: Iron Bug 23.2.2013, 3:44

пример использования можно посмотреть тут, например:
http://stackoverflow.com/questions/12439099/interprocess-reader-writer-lock-with-boost

насчёт использования в качестве статической переменной - не уверена, просто не помню. это надо проверить. завтра попробую.

вообще, boost::interprocess реализован через файлы и, фактически, такой элемент имеет "filesystem persistency" - хз, как по-русски это перевести, но смысл понятен, я думаю: пока явно его не убьёшь, он будет болтаться в виде файла (привязан к сессии юзера, на самом деле). так что там могут получаться эффекты от разных запусков: например, написал софтину, запустил - какой-то элемент остался в общем пространстве (буст ведь не знает, будут ли ещё процессы его использовать или нет, а чтобы его явно удалить, нужно вызывать статический remove). потом, например, ещё раз запустил софтину или поменял что-то и запустил - а "старый" объект-то так и висит в системе. поэтому когда с межпроцессными объектами работаешь - нужно много всякой дополнительной фигни учитывать, это немного сложнее, чем просто межпоточное взаимодействие, потому что всё глобально на уровне системы. иногда бывает, что от старых неудачных запусков осталась какая-то хрень в виде лока, например, и второй раз он его залочить не даст. или что-то подобное. в общем, там могут оказаться довольно неожиданные ситуации, хотя они возникают довольно редко.
чтобы просто убедиться, что это не такой глюк, можно найти хранилище этого самого interprocess'а (под вендой он его создаёт где-то на системном винте, в юзерском каталоге для временных файлов, а под линём - в tmp, если правильно помню, это надо в коде самого буста смотреть или поискать просто каталог с именем interprocess). и внутри него всё грохнуть (т.е. как бы почистить принудительно). а потом снова запустить софтину. если это глюк из-за "застрявших" объектов - ошибка исчезнет. но тут надо будет выяснять, а почему они, собственно, застряли. это уже вопрос реализации логики программы.

Автор: alexy 23.2.2013, 11:30

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

Это мне нужно для веб сервера. Делаю приложение используя wt (http://www.webtoolkit.eu). нужно сделать возможность настройки некоторых особенностей приложения. наример если на site.com/forum работает форум, то на site.com/admin должно стоять приложение, позволяющие администрировать форум. проблема в том, что админов может быть несколько, работать они могут отновременно, да еще и одновременно с пользователями. вот я и думаю в таком смысле: есть класс гуя (admin_gui), который отвечает только за внешниий вид. есть классы менеджеров объектов, которые позволяют настраивать объекты и гуй от них наследуется (class admin_gui : public foo_manager, public ather_foo_manager...).

class guard{
public:
   guard(bool& flag) : flag_(flag) {flag_=true;}
   ~guard() {flag_=false;}
private:
  bool& flag_;
};

class foo_manager{
public:
  foo_manager(){
    namespace pl = std::placeholders;
    bar_connection = bar_sign.connect(std::bind(&foo_manager::on_bar_changed, this, pl::_1, pl::_2));
  }
  ~foo_manager(){
    bar_connection.disconnect();
  }
  int bar()const{return bar_;}
  void bar(const int& n){
      bar_ = n;
      guard g(bar_flag);
      bar_sign();
  }
  virtual foo_bar_changed(int old, int n)=0;
private:
  typedef boost::signals2::signal<void (int, int)> bar_signal;
  static bar_signal bar_sign;
  
  void on_bar_changed(int o, int n){
       if(bar_flag) return;
       bar_ = n;
       foo_bar_changed(o, n);
  }

  boost::signals2::connection bar_connection;

  int bar_; bool bar_flag;
};


Вот сюда и надо добавить синхронизацию, чтобы если он пишет, то не читал в этот момет, и писал по очереде.

Такой метод гуд, или ересь и есть решения лучше?

Автор: Iron Bug 23.2.2013, 12:18

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

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


Автор: alexy 23.2.2013, 12:40

а синхронизация? то есть если один чел меняет что-то, на что другой смотрит, он должен узнать как-то.

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

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

Автор: Iron Bug 23.2.2013, 13:06

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

Автор: alexy 23.2.2013, 13:32

Цитата(Iron Bug @ 23.2.2013, 14:06) *
уведомления клиентам о необходимости обновиться может слать сервер

какой сервер? базы данных что ли?

Автор: Iron Bug 23.2.2013, 16:17

тот, с которым юзеры работают. сам же написал, что это, типа, серверное приложение.

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)