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

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


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

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


 




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


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

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