аналог sched_yield для всего процесса подскажите

elenangel

сабж. такое бывает вообще?

boikodima1

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

elenangel

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

boikodima1

при блокирующем системном вызове так и будет
если у тебя активное ожидание - вызывай тот же yield/nanosleep/select в том треде где оно происходит
зачем както влиять на все треды сразу (особенно, если они при этом не в состоянии сами yield делать)?

elenangel

ну у меня куча тредов, в некоторых блокирующие вызовы, в других по идее надо делать conditional variable для сигнализации о приходе данных, sched_yield неэффективен, он то ли не работает вообще, то ли по кругу между тредами процессор кидает, а в результате 700% нагрузки на 8-ядерной машине. хочется подкостылить временно чем-то вроде него же, но воздействующим на весь процесс. и да, я знаю что активное ожидание антипаттерн и планирую это потом переделать.

Maurog

в результате 700% нагрузки на 8-ядерной машине
что-то вы не то делаете в своем процессе и проблема совсем не sched_* :o

ppplva

На всякий случай, у тебя есть конкурирующие процессы?

elenangel

да, есть. обычное рабочее окружение, плюс клиентское приложение в котором 3 треда, 2 в ожидании cin и recv, один в активном ожидании чтобы сделать send, приблизительно так

ppplva

То есть да, нет? В обычном окружении нет процессов конкурирующих за CPU. Вот у меня сейчас загрузка 0% примерно.
Если так, то читай маны про sched_yield, он так себя и должен вести. Вставляй sleep если нужно отдать CPU в idle.

elenangel

в общем да, браузер, среда разработки, полтора десятка терминалов не конкуренты. конкурент только клиентское приложение с одним тредом в активном ожидании.
можно и sleep сделать, но не хотелось. будет ли достаточно в одном треде делать sleep, а в остальных shed_yield? тупо втыкать usleep(1000) в каждый тред - значит снизить отзывчивость системы до 1мс максимум. можно наверно usleep(1) попробовать, а что тогда делать в сборке под винду?

elenangel

кстати по результатам экспериментов sched_yield на 2003 сервере в программе собранной mingw32 выполняется 15 мс.
как уж оно там реализовано - хз.

bleyman

> тупо втыкать usleep(1000) в каждый тред - значит снизить отзывчивость системы до 1мс максимум. можно наверно usleep(1) попробовать, а что тогда делать в сборке под винду?
В венде sleep(0) yields и всё, да. Я как бы не очень понимаю как ты себе представляешь решение своей проблемы: вот у меня есть тред который жрёт 100% CPU, я из него могу постоянно йелдиться но он же всё равно сразу обратно получает управление и по-прежнему жрёт 100% CPU, what do? Не жрать 100% CPU, that's what.
Алсо, лолд про твою наивную идею что usleep(1) в луникс системе позволит не жрать 100% CPU. Во-первых, там всё так же квантуется время, и теми же самыми 15мс (20 в солярисе во-вторых, ну как ты себе это представляешь, что вообще должно происходить по-твоему, когда ты говоришь usleep(1)?
Короче, вместо того чтобы спрашивать как решить твою долбанутую проблему, спроси как решить проблему которую ты на самом деле хочешь решить. Мы тебе посоветуем как написать код чтобы он не использовал busy wait.

ava3443

Во-первых, там всё так же квантуется время, и теми же самыми 15мс (20 в солярисе)
ИМХО про линукс твоя инфа устарела, и на 2.6 уже не так.
И про солярис тем более: hires_tick и hires_hz в /etc/system - разве не оно?
А по теме - топикстартер дурью мается конечно, надо от busy-waiting избавляться, а не на yield всякие смотреть.

elenangel

 
Алсо, лолд про твою наивную идею что usleep(1) в луникс системе позволит не жрать 100% CPU.

ничего не знаю. регулировал поток отправки пакетов udp вставляя задержку менее миллисекунды этим вашим usleep и все работало.

elenangel

Короче, вместо того чтобы спрашивать как решить твою долбанутую проблему, спроси как решить проблему которую ты на самом деле хочешь решить. Мы тебе посоветуем как написать код чтобы он не использовал busy wait.
ок. суть такова: нужно в одном треде класть эвенты в очередь, тут нет бизивейт, тут есть блокирующие чтения откуда-либо, а в другом - забирать из очереди и обрабатывать, вот тут у меня стоит нечто вроде
 while(isRunning
{
while(!queue.empty
{
IEvent *event = queue.pop;
//some code
delete event;
}
Thread::yieldCurrentThread;
}

как я понимаю, надо сделать вместо yield ожидание условной переменной, которую сигналить из queue.push
пока что все упирается в то, что нужно завернуть pthread_cond_t в класс, а делать это влом

Maurog

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

vall

ничего не знаю. регулировал поток отправки пакетов udp вставляя задер;ку менее миллисекунды этим вашим usleep и все работало.
flow-control методом usleep(10) ? :lol:

elenangel

а чем?

vall

ну логика должна быть чуть более сложной чем константное ожидание.
плюс sleep может прерваться по сигналу. лучше таймеры использовать или нормальный event-loop.

elenangel

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

vall

а, ну тогда сойдёт. лишь бы сеть не завалила ненароком.

elenangel

ну скопипасть какой-нибудь простейший producer-consumer подход
а я разве не его описал, когда упомниал операции с условной переменной?

Maurog

а я разве не его описал, когда упомниал операции с условной переменной?
правильно, только надо его скопипастить, удалить эту ветку и не мучать себя и процессор(ы) :grin:
Оставить комментарий
Имя или ник:
Комментарий: