Поиск:

Ответ в темуСоздание новой темы Создание опроса
> boost::mutex, помогите разобраться с задачей 
V
    Опции темы
JanryMayers
Дата 26.1.2011, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 11.6.2009
Где: Украина, г. Киев

Репутация: нет
Всего: нет



вообщем остановился на таком варианте что скажите?
Код

void mThread::run(){ 
    while(signal){
        if(the_case_in_thread->size() > Y ||
            ((!the_case_in_thread->empty())&&(the_case_in_thread->front()!= element))){
            the_case_in_thread->pop_front();
        }
    the_case_in_thread->push_back(Y, element);
    //сюда ещё добавлю boost::thread::sleep
    }
}


а вот класс с мьютексом
Код

class the_case{
public:
    the_case();
    ~the_case();
    void lock();
    void unlock();
    std::list<size_t>* get_list();
    size_t size();
    bool empty();
    size_t front();
    void pop_front();
    void push_back();
    void push_back(size_t,size_t);
private:
    std::list<size_t> the_list;
    boost::mutex the_mutex;
};
the_case::the_case(){
}
the_case::~the_case(){
}
std::list<size_t>* the_case::get_list(){
    return &the_list;
}
size_t the_case::size(){
    std::cout<<"\nin_size";
    boost::mutex::scoped_lock lock(the_mutex);
    return the_list.size();
}
bool the_case::empty(){
    std::cout<<"\nin_empty";
    boost::mutex::scoped_lock lock(the_mutex);
    return the_list.empty();
}
size_t the_case::front(){
    std::cout<<"\nin_front";
    boost::mutex::scoped_lock lock(the_mutex);
    return the_list.front();
}
void the_case::pop_front(){
    std::cout<<"\nin_pop_front";
    if(!empty()){
        boost::mutex::scoped_lock lock(the_mutex);
        the_list.pop_front();
        std::cout<<"\npop_front";
        lock.unlock();
    }
}
void the_case::push_back(size_t Y,size_t element){
    if(size()<Y){
        boost::mutex::scoped_lock lock(the_mutex);
        the_list.push_back(element);
        std::cout<<"\npush_back "<<element;
        lock.unlock();
    }
}


Это сообщение отредактировал(а) JanryMayers - 26.1.2011, 12:45
PM MAIL   Вверх
azesmcar
Дата 26.1.2011, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 3
Всего: 211



JanryMayers

Первое, что заметил.
Цитата(JanryMayers @  26.1.2011,  12:23 Найти цитируемый пост)
    size_t front();
    void pop_front();

Это ошибка, так нельзя. Да, в обычной ситуации функции front() и pop_front() лучше разделять, так-как они выполняют две задачи, к тому же сделать функцию, выполняющую более одной задачи строго-безопасной в отношении исключений довольно сложно. Но это другой случай. В данный момент перед тобой стоит задача получения элемента в многопотоной среде, с таким раскладом ты можешь получить один элемент с помощью функции front(), потом вытащить элемент с помощью функции pop_front(), но нет никакой гарантии, что ты вытащил именно тот элемент, который получил до этого, так-как между двумя вызовами этих функций другой поток может вставить значение в список и ты удалишь этот элемент даже не зная о нем. Функция pop_front() потокобезопасного списка должна возвращать значение, которое она вытащила. Если нужна строгая безопасность исключений (хотя сомневаюсь) возвращай shared_ptr.
PM   Вверх
borisbn
Дата 26.1.2011, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 48
Всего: 135



и ещё. Ты проверяешь, например в первом потоке
Цитата

if ( !the_case_in_thread->empty() ...

потом второй поток может влезть и удалить последний элемент, а потом первый поток будет делать
Цитата

the_case_in_thread->pop_front()


первое, что приходит в голову, это весь код "бизнесс-логики" засунуть в класс Case и защитить его mutex'ом

Код

void Case:doIt( int Y, int element )
{
        boost::mutex::scoped_lock lock(the_mutex);
        if( the_list.size() > Y ||
            ((!the_list.empty())&&(the_list.front()!= element))){
            the_list.pop_front();
        }
    the_list.push_back(element);
}

а код потока станет таким
Код

void mThread::run() {
    while(signal){
        the_case_in_thread->doIt( Y, element );
        boost::thread::sleep( ??? );
    }
}

это мало чем отличается от варианта, где lock вызывается в потоке в самом начале, а unlock в конце, зато все потокобезопасные вещи инкапсулированы от пользователя.

вариант, конечно, так себе, но всё должно работать...


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
JanryMayers
Дата 28.1.2011, 05:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 11.6.2009
Где: Украина, г. Киев

Репутация: нет
Всего: нет



понятно

я вот нашел такую вещь

SharedLockable Concept

void lock_shared()
bool try_lock_shared()
bool timed_lock_shared(boost::system_time const& abs_time)
void unlock_shared()

тут есть и тайм лок можно использовать вместо sleep?

а также возможно написать mThread::run(), используя try/catch?
PM MAIL   Вверх
azesmcar
Дата 28.1.2011, 06:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 3
Всего: 211



Цитата(JanryMayers @  28.1.2011,  05:48 Найти цитируемый пост)
SharedLockable Concept

SharedLockable не имеет отношения к timed lock-у, для этого можно просто использовать timed_mutex, но зачем он тебе? timed_lock не аналог sleep-а. smile 
Зачем тебе вообще sleep?
PM   Вверх
JanryMayers
Дата 28.1.2011, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 11.6.2009
Где: Украина, г. Киев

Репутация: нет
Всего: нет



Условие задачи такое
Цитата

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


хотел изменяющуюся задержку реализовать sleep и mt19937 генератором... , но думаю есть способ по правильнее, чем этот

Цитата

SharedLockable не имеет отношения к timed lock-у


почему? может я тебя не правильно понял, но вот тут написано что какое то отношение он все таки имеет, по крайней мере функция time_lock_shared

PM MAIL   Вверх
azesmcar
Дата 28.1.2011, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 3
Всего: 211



Цитата(JanryMayers @  28.1.2011,  10:25 Найти цитируемый пост)
почему? может я тебя не правильно понял, но вот тут написано что какое то отношение он все таки имеет, по крайней мере функция time_lock_shared

Ну "какое-то" далекое отношение, по сути shared не для этого ввели, а для shared ownership-а, т.е. для timed_lock-а есть TimedLockable.
http://www.boost.org/doc/libs/1_32_0/doc/h...epts.TimedMutex.
Но все равно, это не то, что тебе нужно.

Цитата(JanryMayers @  28.1.2011,  10:25 Найти цитируемый пост)
Основной поток запускает x вспомогательных, бесконечно добавляющих в некий контейнер свой элемент, потоков с некоторой изменяющейся задержкой. 

что такое "с некоторой изменяющейся задержкой"? Мне эта часть непонятна
Цитата

некоторой изменяющейся

random-ом что ли? хотя в любом случае это sleep.
PM   Вверх
JanryMayers
Дата 29.1.2011, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 11.6.2009
Где: Украина, г. Киев

Репутация: нет
Всего: нет



да рендом. я его(sleep) так написал

Код

void the_thread::sleep(){
    gen.seed(static_cast<unsigned> (std::time(0)));

    const size_t NANOSECONDS_PER_MILLISECOND = 1000000;

        boost::normal_distribution<double> norm_dist(0, 5);
        boost::variate_generator<boost::mt19937&, boost::normal_distribution<double>> normal_sampler(gen, norm_dist);

    size_t rand = boost::lexical_cast<size_t>(normal_sampler());

    boost::xtime the_time;

    the_time.sec = 0;
    the_time.nsec = rand*NANOSECONDS_PER_MILLISECOND;

    m_thread->sleep(the_time);
}


правда в строчке 

Код

    size_t rand = boost::lexical_cast<size_t>(normal_sampler());


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

в этом классе
Код

class the_case{
public:
    the_case();
    ~the_case();
    void lock();
    void unlock();
    std::list<size_t>* get_list();
    size_t size();
    bool empty();
    size_t front();
    void pop_front();
    void push_back();
    void push_back(size_t,size_t);
private:
    std::list<size_t> the_list;
    boost::mutex the_mutex;
};


говорят, что нельзя выдавать указатель на данные под mutex'ом в этой строчке
Код

    std::list<size_t>* get_list();

const std::list<size_t>* the_case::get_list(){
    return &the_list;
}


какой выход из такой ситуации?

Это сообщение отредактировал(а) JanryMayers - 30.1.2011, 18:49
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0613 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.