Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> альтернатива while(1) 
:(
    Опции темы
box
Дата 14.10.2013, 01:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 506
Регистрация: 27.2.2007

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



всем привет !
есть ли альтернатива while(1) для треада если он начинается с цыкла 
надо что бы треад не жрал все процессорное время. счетчики имеются но как запустить процесс если счетчик int > 0 ?
PM MAIL   Вверх
_zorn_
Дата 14.10.2013, 07:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(box @  14.10.2013,  09:29 Найти цитируемый пост)
надо что бы треад не жрал все процессорное время.

Код
sleep(1);

Цитата(box @  14.10.2013,  09:29 Найти цитируемый пост)
счетчики имеются но как запустить процесс если счетчик int > 0 ? 

Код
do{
i--;
}while(i>0)


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

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



Цитата(box @  14.10.2013,  02:29 Найти цитируемый пост)
что бы треад не жрал все процессорное время

вешай поток на переменную условия, что-то типа этих https://computing.llnl.gov/tutorials/pthrea...ditionVariables

По остальной части вопроса всё аналогично обычным циклам (можно использовать for или проверку условия и break в случае невыполнения, для прерывания цикла).
PM MAIL   Вверх
baldina
Дата 14.10.2013, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(box @  14.10.2013,  01:29 Найти цитируемый пост)
что бы треад не жрал все процессорное время

надо будить его по событию. что-то типа std::condition_variable::wait(), или платформозависимое (WaitFor.../pthread_cond_wait/select)
PM MAIL   Вверх
box
Дата 14.10.2013, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 506
Регистрация: 27.2.2007

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



нет , вы не поняли , sleep не подходит ибо за время sleep может накопиться очень много пакетов которые потом прийдется разгребать , вообщем надо что бы при поступлении нового пакета один треад подавал сигнал другому и запускал while(int > 0) где int целочисленная глобальная переменная 
PM MAIL   Вверх
null56
Дата 14.10.2013, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

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



box, тебе ответил baldina, что можно заставить спать твой while тред, а из треда, где идет обработка входящих пакетов, ты можешь сделать wake_up твоему while треду... см
Цитата

man 3 pthread_cond_wait


будет что - то типа

Код

// тред будящий
// пришел пакет
pthread_cond_signal // буди рабочий тред



Код

// тред рабочий
while (пока работает твоя прога)
{
   pthread_cond_wait()
   while (int > 0)
   {
   // твой алгоритм
   }
}


есть альтернативный вариант спать на epoll, select в твоем while треде, но это возможно не твой случай

PM MAIL   Вверх
box
Дата 14.10.2013, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 506
Регистрация: 27.2.2007

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



не хочет засыпат треад , делаю так :

Код

pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv; 

// в треаде который надо запускать 

pthread_mutex_lock(&mu);  
while(1){//бесконечный цыкл что б треад не спал
pthread_cond_wait(&cv, &mu); 

while(limit1-- > 0){
//тут чекаем пакеты
}

}
pthread_mutex_unlock(&mu);  

//в треаде который запускает другой

    while (limit-- > 0) {

        pthread_cond_signal(&cv); //запускаем треад при поступлении пакета
    }

но проц все равно грузится под завязку

PM MAIL   Вверх
akizelokro
Дата 14.10.2013, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Крокодил
**


Профиль
Группа: Участник
Сообщений: 761
Регистрация: 30.7.2007

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



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



Это сообщение отредактировал(а) akizelokro - 14.10.2013, 16:02


--------------------
a = a + b; b = a - b; a = a - b;
PM MAIL   Вверх
Alexeis
Дата 14.10.2013, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Решал аналогичную задачу под винду. Создавал что-то типа диспетчера задач, но он также должен был реагировать полученные оконные сообщения.
Функция MsgWaitForMultipleObjectsEx ждет таймаут ~20мс (chkTimeout) только в случае если не пришло сообщений от винды или если не произошло запланированных событий. Если что-то из этого произошло, то ожидание прерывается досрочно и начинается обработка (WaitObjHandleList - это вектор хэндлов)
Код

    try
    {
        SafeOp->Enter();
        FStarted = true;

        do
        {   //ждем список объектов ожидания
            DWORD res = MsgWaitForMultipleObjectsEx(WaitObjHandleList.size(), &WaitObjHandleList[0], chkTimeout,
                                                   QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);

            //выход из WaitForMultipleObjects по событию (нулевой объект заглушка)
            if ((res >= WAIT_OBJECT_0)&&(res < WAIT_OBJECT_0 + WaitObjHandleList.size()))
            {
                size_t num = res - WAIT_OBJECT_0;
                if (num < WaitObjHandleList.size()) //если сработало событие ожидание, то вызываем его обработчик
                {
                    CWaitObj clsr = WaitObjList[num];
                    (*clsr.Clbk)(clsr.UsrData, clsr.WaitObj);
                }
                //иначе ошибка (ничего не делаем)
            }
            else if ...



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

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

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


Опытный
**


Профиль
Группа: Участник
Сообщений: 506
Регистрация: 27.2.2007

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



пытаюсь расспаралелить по треадам 

Код

#define NUMTHRDS 10

std::mutex mtx[NUMTHRDS];
std::condition_variable cv[NUMTHRDS];
std::unique_lock<std::mutex> lck[NUMTHRDS];

int i;
...
  lck[i](mtx[i]);

while(1){

 cv[i].wait(lck[i]); 
 
while(limit1-- > 0){
....



при компиляции выдает :

error: type 'std::unique_lock<std::mutex>' does not provide a subscript operator
         lck[i](mtx[i]);
         ~~~^~
error: type 'std::unique_lock<std::mutex>' does not provide a subscript operator
 cv[i].wait(lck[i]);

надо что бы можно было централизованно лочить/разлочить цыкл while(1) в любом из треаде

Это сообщение отредактировал(а) box - 14.10.2013, 22:08
PM MAIL   Вверх
akizelokro
Дата 15.10.2013, 07:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Крокодил
**


Профиль
Группа: Участник
Сообщений: 761
Регистрация: 30.7.2007

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



А вообще какая многопоточная модель используется? Я так понимаю, что не несколько равноценных потоков. Скорее всего, либо модель с основным потоком и несколькими второстепенными? Или конвейерная обработка?
Если модель с основным потоком и несколькими второстепенными (зависимыми), то там уже сам бог велел делать различные приоритеты выволнения потоков. Если конвейерная модель, то можно попробовать осуществлять запуск потоков из первого, начинающего конвейерную обработку.

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

Цитата

нет , вы не поняли , sleep не подходит ибо за время sleep может накопиться очень много пакетов которые потом прийдется разгребать , вообщем надо что бы при поступлении нового пакета один треад подавал сигнал другому и запускал while(int > 0) где int целочисленная глобальная переменная 

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


Код

while(1)
{
  if( ... )
  {
  // проверка, появились ли пакеты для обработки или на несколько условий для начала обработки
  // если появились, обработка до последнего
  }
  else
    sleep(35);
// 
}


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


Это сообщение отредактировал(а) akizelokro - 15.10.2013, 08:44


--------------------
a = a + b; b = a - b; a = a - b;
PM MAIL   Вверх
vinter
Дата 15.10.2013, 08:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



box, лучше напиши, что ты хочешь сделать. Конечную цель. И ОС + компилятор, которыми ты собрался решать задачу.

P.S. по-русски правильно говорить поток(ну или в крайнем случае тред), но никак не треад


--------------------
Мой блог
PM MAIL WWW   Вверх
Alexeis
Дата 15.10.2013, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Цитата(akizelokro @  15.10.2013,  08:40 Найти цитируемый пост)
Если модель с основным потоком и несколькими второстепенными (зависимыми), то там уже сам бог велел делать различные приоритеты выволнения потоков.

  Если поток зашел в бесконечный цикл, то никакой приоритет не поможет снизить нагрузку. Такой поток загрузит ядро на 100%. Поток, который в данное время не занят, должен спать и просыпаться по некоторому условию только, когда для него есть работа. Исключение может быть сделано для кратковременной блокировки, время которой сопоставимо со временем перехода в режим ядра. В этом случае можно применить спин блокировку. 


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

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

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


Крокодил
**


Профиль
Группа: Участник
Сообщений: 761
Регистрация: 30.7.2007

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



Цитата

Если поток зашел в бесконечный цикл, то никакой приоритет не поможет снизить нагрузку. Такой поток загрузит ядро на 100%. Поток, который в данное время не занят, должен спать и просыпаться по некоторому условию только, когда для него есть работа. Исключение может быть сделано для кратковременной блокировки, время которой сопоставимо со временем перехода в режим ядра. В этом случае можно применить спин блокировку. 
 

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


--------------------
a = a + b; b = a - b; a = a - b;
PM MAIL   Вверх
akizelokro
Дата 15.10.2013, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Крокодил
**


Профиль
Группа: Участник
Сообщений: 761
Регистрация: 30.7.2007

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



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


--------------------
a = a + b; b = a - b; a = a - b;
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

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


 




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


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

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