Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Семафор: динамическое изменение кол-ва потоков 
:(
    Опции темы
Alca
Дата 4.2.2010, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Использую семафор для лимитирование кол-ва потоков.
Как динамически измененять кол-во потоков? Как такое можно сделать?

Т.е. после создания семафора ф-ей 
Код

::CreateSemaphore(lpsaAttributes, liInitialCount, liMaxCount, pcszName);

надо изменить (увеличить, уменьшить) кол-во работающих потоков


--------------------
PM WWW ICQ Skype Jabber   Вверх
mrbrooks
Дата 4.2.2010, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


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

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



ReleaseSemaphore
PM MAIL   Вверх
Alexeis
Дата 4.2.2010, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



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


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alca
Дата 4.2.2010, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



ReleaseSemaphore - это увеличить. А как уменьшить?


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 4.2.2010, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(Alca @  4.2.2010,  10:29 Найти цитируемый пост)
А как уменьшить? 

WaitForSingleObject уменьшит. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alca
Дата 4.2.2010, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

Если у тебя потоки создаются в отдельном потоке-фабрике, который ожидает на WaitForSingleObject ,

Так оно и есть


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 4.2.2010, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



  По этой теме есть оч. хорошая книжка Рихтера. Последнее издание называется Windows via С/С++ . Но подойдет и более старое издание. Тема управления потоками и объектами синхронизации раскрыта отлично. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alca
Дата 4.2.2010, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Код

template<class TaskT>
BOOL CXThreadPool<TaskT>::bSetMaxTasks(UINT uiNum)  {
    BOOL bRes = FALSE;

    bRes = _m_semSemaphore.bRelease(uiNum/*1*/, NULL);  
    /*DEBUG*/XASSERT_RET(FALSE != bRes, FALSE);    //валиться здесь, LastError:     298

    _m_uiMaxRunningTasks = uiNum;

    return TRUE;
}


Код

LastError:     298 - "Слишком много попыток занесения события для семафора."


Это сообщение отредактировал(а) Alca - 4.2.2010, 11:44


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 4.2.2010, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Alca, может устанавливается значение выше чем liMaxCount?


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alca
Дата 4.2.2010, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

Alca, может устанавливается значение выше чем liMaxCount?

Да, было дело.

--------
Надо увеличить кол-во потоков. Сначала ставлю семафор на 4 потока
Код

::CreateSemaphore(lpsaAttributes, 4/*liInitialCount*/, 4/*liMaxCount*/, pcszName);

Потом пытаюсь увеличить на 2, т.е. устанавливаю 6:
Код

BOOL CXThreadPool::bSetMaxTasks(UINT uiNum)  {
    BOOL bRes = FALSE;
    
    //_m_uiMaxRunningTasks - текущий  лимит потоков (сейчас 4)
    //uiNum                - желаемый лимит потоков    (хочу 6)
    

    //увеличение лимита
    if (_m_uiMaxRunningTasks < uiNum) {
        bRes = _m_semSemaphore.bRelease(uiNum - _m_uiMaxRunningTasks, NULL);  
        /*DEBUG*/XASSERT_RET(FALSE != bRes, FALSE);    
    }
    
    //уменьшение лимита
    //...

    _m_uiMaxRunningTasks = uiNum;

    return TRUE;
}
...
bSetMaxTasks(6);    //хочу увеличить кол-во потоков

В диспечере задач кол-во потоков увеличилось только на единицу, хотя я сбросил семафор на 2-ку.
Эссерт не срабатывает.
 smile 

Это сообщение отредактировал(а) Alca - 4.2.2010, 13:22


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 4.2.2010, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Чтобы можно было 6 нужно
Код

::CreateSemaphore(lpsaAttributes, 4, 6, pcszName);


А, вообще, почему бы не поставить сразу 64? или 128? 
Код

::CreateSemaphore(lpsaAttributes, 4, 128, pcszName);


Чтобы уменьшить число запущенных потоков нужно просто завершить один из них.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alca
Дата 4.2.2010, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Alexeis, спасибо. Увеличивать число потоков получилось. 
А уменьшить кол-во потоков не получается. 
Завершил я N-ое кол-во "лишних" потоков, 
но их  число не уменьшилось (смотрел в диспетчер задач), 
т.к. запустилась следующяя партия потоков, стоящих в очереди.
Код

bRes = _m_semSemaphore.bCreate(NULL, _m_uiMaxRunningTasks, 1024, NULL);  
//...    
template<class TaskT>
BOOL CXThreadPool<TaskT>::bSetMaxTasks(UINT uiNum)  {
    BOOL bRes = FALSE;

    //-------------------------------------
    //увеличить
    if (_m_uiMaxRunningTasks < uiNum) {
        bRes = _m_semSemaphore.bRelease(uiNum - _m_uiMaxRunningTasks, NULL);  
        /*DEBUG*/XASSERT_RET(FALSE != bRes, FALSE);    
    }

    //-------------------------------------
    //уменьшить
    if (_m_uiMaxRunningTasks > uiNum) {
        CXCriticalSectionLocker CS(_m_csList);    //лочим std::list

        size_t i            = 0;                            //счетчик удаленных потоков
        size_t iDeleteTasks = _m_uiMaxRunningTasks - uiNum;    //сколько надо удалить потоков

        for (std::list<TaskT *>::iterator it = _m_lstpthTasks.begin();    it != _m_lstpthTasks.end(); ++ it)    {
            bRes = (*it)->bExit(/*ulTimeout*/5000);    //говорим потоку, что пора завершаться
            /*DEBUG*/XASSERT_RET(FALSE != bRes, FALSE);

            ++ i;

            if  (i >= iDeleteTasks) {
                break;
            }
        }    
    }


    _m_uiMaxRunningTasks = uiNum;

    return TRUE;
}
//---------------------------------------------------------------------------


Добавлено через 11 минут и 5 секунд
 smile 


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 4.2.2010, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(Alca @  4.2.2010,  15:51 Найти цитируемый пост)
Alexeis, спасибо. Увеличивать число потоков получилось. 
А уменьшить кол-во потоков не получается. 

  Чтобы завершить поток достаточно позволить функции потока выполниться до конца. Если это пул потоков, то скорее всего имеется бесконечный цикл, который нужно прервать, а в потоке-фабрике дождаться полного завершения при помощи WaitForSingleObject(ThreadHandle, 1000) . После этого можно быть уверенным что поток завершился корректно. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alca
Дата 5.2.2010, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Alexeis, именно так я и делаю, в это методе все реализовано:
Код

bRes = (*it)->bExit(5000);    //говорим потоку, что пора завершаться


Добавлено через 51 секунду
Потоки завершаются, смотрел лог.


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 5.2.2010, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(Alca @  5.2.2010,  10:31 Найти цитируемый пост)
Потоки завершаются, смотрел лог. 

Ну раз завершаются значит все в порядке smile 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alca
Дата 5.2.2010, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Но у меня при завершении потока срабатывае колбэк функция, в этой ф-ии я делаю:
Код

bRes = _m_semSemaphore.bRelease(1, NULL); 

Следовательно, потом запускаются следующие потоки, стоящие в очереди.
Т.е. мне надо как-то уменьшить барьер (кол-во работающих потоков), как это сделать?
Или может все-таки соорудить семафор на ивентах, такое реально? 


--------------------
PM WWW ICQ Skype Jabber   Вверх
xvr
Дата 5.2.2010, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Alca @ 5.2.2010,  11:56)
Но у меня при завершении потока срабатывае колбэк функция, в этой ф-ии я делаю:
Код

bRes = _m_semSemaphore.bRelease(1, NULL); 

Т.е. мне надо как-то уменьшить барьер (кол-во работающих потоков), как это сделать?

Заблокировать вызов callback функции (в данном случае)

PM MAIL   Вверх
Alca
Дата 5.2.2010, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



А как насчет ивентов, можно ли реализовать класс с соответствующим функционалом?


--------------------
PM WWW ICQ Skype Jabber   Вверх
xvr
Дата 5.2.2010, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Alca @ 5.2.2010,  12:56)
А как насчет ивентов, можно ли реализовать класс с соответствующим функционалом?

Конечно можно из эвентов сделать семафор, и из семафора можно сделать эвент. А еще можно топором брится, вот только зачем? Семафор, сделанный из эвентов, будет работать так же, как и натуральный  smile 
А функционал семафора в данном случае наиболее точно подходит для реализации функционала класса пула потоков.

А для динамической модификации количества потоков в пуле очевидно должна быть поддержка и в самих потоках

PM MAIL   Вверх
Alca
Дата 5.2.2010, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

А для динамической модификации количества потоков в пуле 
очевидно должна быть поддержка и в самих потоках

То есть?



--------------------
PM WWW ICQ Skype Jabber   Вверх
xvr
Дата 5.2.2010, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Alca @ 5.2.2010,  13:12)
Цитата

А для динамической модификации количества потоков в пуле 
очевидно должна быть поддержка и в самих потоках

То есть?

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

PM MAIL   Вверх
Alca
Дата 5.2.2010, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



xvr, ясно


--------------------
PM WWW ICQ Skype Jabber   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

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


 




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


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

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