LINUX.ORG.RU

А как в других ЯП разруливают блокирующие функции?

 


0

2

Возможно спрошу криворуко, звыняйте.

Вот есть две функции-примера, неважно на каком ЯП:

function first() {
  printf("Out 1\n");
  sleep(1);
}

function second() {
  printf("Out 2\n");
  sleep(3);
}

function main() {
 while(true) {
  first(); // Эта функция не выполнится пока second() не завершится
  second(); // Эта функция не выполнится пока first() не завершится
 }
}

Каким обычно способом решается вопрос блокировок в коде?

★★★★★
Ответ на: комментарий от alysnix

в нормальном софте слипов не бывает

увидел слип - бей лопатой по смотровым отверстиям автора!

Какой дикий, неприкрытый непрофессионализм. Это же явное 4.2, куда модерация смотрит.

sleep/yield/NOP это база вычислений основанная на тактах. Куда вы лезете вообще со своими ошметками знаний?

Obezyan
()
Ответ на: комментарий от hippi90

В C можно где нужно добавить синхронизацию, а где не нужно не добавлять. А тут хрен знает куда рантайм полезет в конкретном случае. Может решит что пора запустить gc и пощупать переменные, с которыми работают другие треды?

cobold ★★★★★
()
Ответ на: комментарий от alysnix

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

Тут варианта два, либо cron это безответственная, низкой временной точности пикалка либо вы - идиот который не понимает что он несет.

По-моему, тут выбор без выбора.

Obezyan
()
Ответ на: комментарий от anonymous

Ты обосрался с шаред принтерами и решил продолжить словесный понос здесь

не голоси. просто предложи, как можно использовать стеклесс «многозадачность» в задаче клиента.

ответ - никак, потому что стеклесс и однотред это вообще не «многозадачность».

только ты ответ не подглядывай.

alysnix ★★★
()
Ответ на: комментарий от Obezyan

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

и периодичность действий будет Tдействия+Tслипа. потому никакой крон на этом построен быть не может.

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

и идиот который не понимает - это вы милейший.

alysnix ★★★
()
Ответ на: комментарий от Obezyan

задачка:

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

ps. там просто функция крона, слип на сколько-то секунд. не имеет отношения к обсуждению. то есть если клиенту надо слип - нате вам слип.

alysnix ★★★
()
Ответ на: комментарий от zurg

измеряешь время работы функции, вычитаешь из часа, засыпаешь на эту разницу

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

alysnix ★★★
()

Рекомендую в примере заменить sleep() на very_long_action(), а то тут по случаю пятницы некоторые уже в энергосберегающий режим перешли и совсем не одупляют, что вы хотите.

apt_install_lrzsz ★★★
()
Ответ на: комментарий от alysnix

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

zurg
()
Ответ на: комментарий от zurg

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

разговор был о слипе, а не «знании абсолютного времени»… естессно вам надо привязываться к абсолютному времени, а не к интервалам, что дает слип.

что я и сказал - слипы для «безответственной привязки ко времени, когда на точность положили». или для задания малопонятных интервалов, с непойми каким временем реального срабатывания всего этого.

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

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 2)
Ответ на: комментарий от windows10

Задача: выводить в окно, название каждой сканируемой директории. Для этого в середине этого рекурсивного цикла вызывается GTK-шная функция, если точнее gtk_label_new, которая выводит название директории в виджет.

Замени «каждую» на «текущую».

Как и все подобные задачи с GUI.

  • Есть поток с GUI.
  • Есть рабочий поток.
  • Есть «общая переменная» в которую пишет рабочий и читает GUI.
  • Эта «общая переменная» должна быть защищена или мютексом или атомиком.
  • GUI поток должен периодически считывать. Можно настроить это делать на каждое изменение. Но вполне достаточно и раз 10 в секунду это делать.
  • «Общая переменная» может быть глобальной, или тупо указателем на динамическую память, или Message Queue на один элемент.
AlexVR ★★★★★
()
Ответ на: комментарий от windows10

Не читал ваш тред. Ты про invoke пишешь? Это когда из другого потока пытаются залезть в поток GUI. Встречается под разными именами, но обычно invoke-что-там. Про это речь? А то тред читать неприятно

anonymous
()
Ответ на: комментарий от Obezyan

sleep/yield/NOP это база вычислений основанная на тактах. Куда вы лезете вообще со своими ошметками знаний?

так я узнал термин - «вычисления основанные на тактах». что можно «вычислять» на тактах? прям какие-то новые мегазнания.

але. sleep вообще не про такты, он внутри работает на таймере, просто вычисляется его время срабатывание как текущее(во время вызова слип), плюс указанный интервал.

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

yield - это ручное переключение треда или корутины. к тактам отношения не имеет.

а nop - это команда проца - не делать ничего.

как это у вас сложилось в «вычисления основанные на тактах» - неясно. если есть пояснения давайте их. ну или не лезьте со своими ошметками нопов, йелдов, и слипов.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

так я узнал термин - «вычисления основанные на тактах»

Лучше поздно, чем никогда. Процессор работает с ТАКТОВОЙ частотой. Вычисления на процессоре производятся тактами, будь то ЦПУ или ГПУ.

yield - это ручное переключение треда или корутины. к тактам отношения не имеет.

это пропуск своего шага в цикле такта

а nop - это команда проца - не делать ничего.

те то что делает проц когда работает sleep

Вам бы базу подтянуть хотя бы.

Obezyan
()
Ответ на: комментарий от Obezyan

Вычисления на процессоре производятся тактами, будь то ЦПУ или ГПУ.

и это говорит «профессионал»? для процессоров со спекулятивным исполнением? да он может за такт исполнять несколько команд, причем еще промазывать со спекуляцией.

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

к клокам есть привязки. но это сигнал от блока таймера. к клокам проца не имеет отношения.

это то что делает проц когда работает sleep. Вам бы базу подтянуть хотя бы.

аааааа! это тоже профессионал? при слипе тред снимается с шедулера и вообще не работает. его код не исполняется никак.

nop - это команда, которая не делает ничего, но процессор УВЕЛИЧИВАЕТ! счетчик команд. пропускает команду и берет следующую. то есть тред активен.

вы вообще не понимаете ничего тут.

alysnix ★★★
()
Ответ на: комментарий от Obezyan

Так эти функции просто по очереди блокируют тред на какое-то время, не? Ни первая второй не мешает, ни вторая первой.

А, понел. Я-то думал, что автору там какой-то дедлок примерещился, а оно вон оно что. Тред выполняет код последовательно, беда-то какая.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от Obezyan

дарагуша. тред «спит» означает что instruction pointer не указывает на его код, и его инструкции не исполняются, а текущий указатель стека не указывает на стек треда.

nop - это команда которая реально декодируется, но все ее действие - лишь увеличить IP. на ней можно сделать только кратковременный слип, - частный случай нормального слипа, чтобы не возиться с таймером.

настоящий слип это переход из состояния активного треда в состояние спящего на какой-то системной очереди. настоящий слип не сделать на нопах - это просто зря загрузит процессор. он будет крутиться в цикле, ДЕКОДИРУЯ нопы, час например. опять же поскольку исполнение спекулятивное - вообще непонятно, сколько он будет исполнять nop.

alysnix ★★★
()
Ответ на: комментарий от Obezyan

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

давайте подведем итог, и суммируем ваши заблуждения.

nop это просто однобайтовая команда, она честно декодируется, а никакой не «слип».

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

сон - это когда на данный тред исполнение не переключается (ip,sp,регистры), и соответственно никакой его nop исполняться не может.

«циклы» в современном проце с его спекуляциями и кешами, понятие довольное условное. «вычисления основанные на циклах» - это какой-то немыслимый трешак.

для слипов используются клоки таймерных прерываний. как основа работы таймеров.

и поздравляю с медалью за профессионализьм.

alysnix ★★★
()
Ответ на: комментарий от alysnix

nop это просто однобайтовая команда, она честно декодируется, а никакой не «слип».

Так я и не писал что это sleep, также как и yield это не sleep. Я перечислил управляющие команды которые позоляет избежать выполнения в синхронном режиме как на высоком уровне (яп) так и на низком (asm).

Вы же пишите определения и пытаетесь притянуть меня что я против них, это так не работает, переключение оппонента в режим оправдывания со мной не прокатит.

Obezyan
()
Ответ на: комментарий от alysnix

в реальности правильно делается так. заводится таймер, который срабатывает каждый час

лицоладонь.

Ты же понимаешь, что таймер будет реализован sleep’ам? Таймауты в poll/select/epoll — те же слипы. По сути sleep скорее всего и будет через select или poll реализован.

i-rinat ★★★★★
()
Ответ на: комментарий от alysnix

для слипов используются клоки таймерных прерываний. как основа работы таймеров.

Окей, я дочитал досюда и наконец-то понял, где тебя переклинило.

Ты говоришь про работу прошивки на голом железе, скорее всего на каком-нибудь микроконтроллере, где есть возможность зароутить таймер на прерывание и повесить на это прерывание обработчик. В твоей реальности sleep будет реализован пустым циклом. Что очевидно не самый лучший подход.

Остальные в треде говорят про юзерспейс линукса. Понимаешь, тут есть ядро, которое разруливает исполнение процессов и тредов, и призвано обрабатывать ситуацию, когда потоков больше, чем физических ядер. В юзерспейсе можно спокойно создать десяток потоков и дать им спать sleep’ами. На каких-то несложных нагрузках это вполне допустимо, оверхед не будет слишком большим. А вот возможности подцепиться на прерывания от таймера в юзерспейсе нет. Тут можно только попросить ядро вернуть управление из select/poll по таймауту. Но это не точно.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

таймер будет реализован sleep’ам? Таймауты в poll/select/epoll — те же слипы. По сути sleep скорее всего и будет через select или poll реализован.

Не будет. Системные вызовы sleep/poll/select приводят к разной работе внутри ядра. Но концептуально, можно посчитать что с точки зрения пользовательского процесса, это один и тот же sleep, ок.

Хотите сказать, что можно потом sleep прервать сигналом из другого потока/процесса и так из удобрений и веток соорудить асинхронность? Можно конечно, но зачем.

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

opcode
()
Последнее исправление: opcode (всего исправлений: 1)
Ответ на: комментарий от i-rinat

А вот возможности подцепиться на прерывания от таймера в юзерспейсе нет.

Можно использовать связку из timerfd_create и poll/select, результат будет очень похож, если я правильно понял условие.

opcode
()
Ответ на: комментарий от i-rinat

Ты говоришь про работу прошивки на голом железе, скорее всего на каком-нибудь микроконтроллере, где есть возможность зароутить таймер на прерывание и повесить на это прерывание обработчик.

покажь, где я такое говорил. я везде говорил, что слип это засыпание треда на очереди к системному таймеру(не прерыванию, але).

я вообще не говорю про линух(и никто этого не спицифицировал). а про «проектирование кернелов».

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

это в твоей с обизяном реальности это реализуется «пустым циклом», в моей - нет.

А вот возможности подцепиться на прерывания от таймера в юзерспейсе нет.

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

Тут можно только попросить ядро вернуть управление из select/poll по таймауту. Но это не точно.

а это и реализовано через очереди. тред(своим хендлом) вызывая полл встает в очередь куда-то там, как только возникнет нужный ивент - в данном случае от таймера, тред выпихивают из очереди и переводят в активное состояние.

alysnix ★★★
()
Ответ на: комментарий от opcode

Хотите сказать, что можно потом sleep прервать сигналом из другого потока/процесса и так из удобрений и веток соорудить асинхронность? Можно конечно, но зачем.

rinat просто не понимает, как это работает и должно быть реализовано. он человек юзерспейса с претензиями.

глубже poll он окунуться не может. как работают «ожидания событий» - не врубается.

и линух тут не причем. это общие механизмы, они везде одинаковы.

alysnix ★★★
()
Ответ на: комментарий от Obezyan

Собственно, ориентироваться на тактовою частоту процессора, при вычислении временных промежутков никак нельзя. Об этом прямо говорится где-то в недрах документации Intel (где точно, к сожалению, не помню, так как уже давно не касался Ассемблера). Происходит это по следующим причинам (те, что помню):

  • У каждого ядра свой счётчик тактов, не связанный с счётчиками других ядер.
  • Счётчики тактов изначально не синхронизированы, так как ядра запускаются не в один и тот же момент времени.
  • Счётчик тактов обновляется лишь когда ядро не спит.
  • Не все такты одинаковой длительности, так как частота конкретного ядра варьируется во время работы, независимо от других ядер.
  • Исполнение одних и тех же операций занимает различное время, так как зависит от переименования регистров, свободных исполнительных устройств (которые имеют разную пропускную способность, для одних и тех же операций), наличия операндов в кеше, предсказателя переходов, работы внутреннего планировщика, выстраивания порядка видимости операций и тучи других параметров.
  • Многие инструкции не доходят даже до планировщика, заканчивая свой путь после декодирования, еще на подготовительных этапах. Например инструкции копирования содержимого из одного регистра в другой, не затрагивают даже регистровую память, так как на внутреннем уровне имена регистров общего назначения, являются по сути, лишь псевдонимами для результатов работы других инструкций, так как в микроархитектурах для оптимизации широко используется SSA-форма внутреннего представления команд.
  • Инструкции nop большинством современных микроархитектур просто игнорируются, и не занимают никакого времени, а служат лишь для выравнивания остальных инструкций в байткоде.
  • Инструкции pause используемые в speenlock-ах являются не более чем подсказкой планировщику, и не имеют строго обозначенного времени выполнения.
QsUPt7S ★★★
()
Ответ на: комментарий от alysnix

nop это просто однобайтовая команда

<зануда_mode>Одна команда nop может занимать от 1 до 9 байтов в байткоде.</зануда_mode>

QsUPt7S ★★★
()
Последнее исправление: QsUPt7S (всего исправлений: 1)

Добрый день. Сам всё развожу по потокам, доступ к общим данным контролирую мьютексами, семафоры нигде не использую. Это и в играх и в системных приложениях. Например, сейчас проектик доделываю, там много функционала и всё по потокам распихал. Удобно очень. Прям сейчас, например, клиент под виндой пять потоков сделал, под лиуксом не могу посмотреть, т.к. там прям «плаваю» в плане админства. Под мак не компилю по той же причине (плохой админ). При этом всё работает как на коре ай7, так и на интел атомах и везде нагрузка получается околонулевая. В общем авторитетные мнения очень ценны конечно же, но как по мне, разнесение задач по потокам, это нормальное решение.

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

strange2007
()