Работа main() при наличии 1 ядра

Страницы: 1
RSS
Работа main() при наличии 1 ядра
 
Здравствуйте, хочу поставить Quik на VPS сервер чтобы работал там круглосуточно, волнует вопрос, как будет работать main() в отдельном потоке при наличии только 1 ядра? Все ли будет работать или нужно минимум 2. Поправьте если я чего-то не понимаю, спасибо
 
А main-то какое до этого дело? Лично у меня main вообще просто спит, и раз в 15 секунд вызывает утилиту, которая чего-то там опрашивает и принимает какие-то решения. Ну и, насколько я понимаю, любая задача, которая работает на нескольких ядрах, обязана работать и на одном ядре.

Квик-то,может, и будет работать круглосуточно. А биржа?  :smile:  
 
Владимир, По факту main будет работать в том же потоке что и квик, и если в нем часть функционала то будет немного медленнее работать
 
Христиан, УПС! Вы уверены?! А какое отношение потоки имеют к ядрам? Мне доводилось писать многопоточные приложения ещё когда никто о ядрах и слыхом не слыхивал, а сопроцессор был отдельным камнем.
 
Цитата
Христиан написал:
Здравствуйте, хочу поставить Quik на VPS сервер чтобы работал там круглосуточно, волнует вопрос, как будет работать main() в отдельном потоке при наличии только 1 ядра? Все ли будет работать или нужно минимум 2. Поправьте если я чего-то не понимаю, спасибо
Потоки будут выполняться по очереди и не будет параллельности.
 
Цитата
Христиан написал:
main будет работать в том же потоке что и квик
Поток это логическая сущность, ядро - физическая. При наличии нескольких ядер винда тоже не очень охотно перебрасывает поток на другое ядро, чтобы кэш туда-сюда не перетаскивать (посмотрите в диспетчере задач, пока одно ядро менее половины загружено, остальные почти простаивают). Да и синхронизация в луа устроена так, что мейн и колбеки в одном скрипте все равно по очереди выполняются, т.е. в каждый момент времени с луа работает либо мейн, либо колбек. Если грузите длл, сишные функции без лока выполняются, но тоже выгоду заметите, если такая функция что-то достаточно тяжелое делает без обращений к луа.
 
Александр, Смотря что считать параллельностью. Квантование как раз и придумано для обеспечения параллельности. :)
 
Anton, А у меня ни main, ни колбеков - кррысота!  :smile:  
 
Владимир, ну Диоген вон в бочке жил вообще, просил только солнце не загораживать.
 
Anton, А зачем из бочки-то вылезать?  :smile: Терминал общается с сервером, а мы - с терминалом!
 
Цитата
Владимир написал:
А зачем из бочки-то вылезать?
"Why get out from a tank?" прочитал я на автомате. Действительно, вай.

Цитата
Владимир написал:
а мы - с терминалом
Только торгуем не с терминалом и даже не с сервером и даже не с аркой и даже не с биржей. О как все сложно.
 
Anton, В УПОР не вижу никаких сложностей! Сегодня попробую настроить скрипт на слежение, пока без заявок. Чтобы орал: "ЭЙ! Не хочешь вот эту акцию купить (продать)"?
 
Цитата
Anton написал:
в каждый момент времени с луа работает либо мейн, либо колбек.
    мейн и колбеки работают в разных потоках. Если ЦП имеет оно ядро, то процитированное выше верно, Если ядер несколько, то, может быть ситуация, когда мейн и колбеки работают параллельно.
 
Цитата
TGB написал:
Если ядер несколько, то, может быть ситуация, когда мейн и колбеки работают параллельно.
Выделю в процитированном для привлечения внимания
Цитата
в каждый момент времени с луа работает либо мейн, либо колбек.
Про сишные функции, работающие без лока, там тоже написано. Вот если вы в сишной функции луа не трогаете, то работаете параллельно, как только полезли в lua_что-нибудь, встали на локе, пока второй поток не соизволит вас пустить, то есть не вывалится тоже в сишную функцию. Написанный только на луа код будет выполняться строго последовательно короткими перебежками от сишной функции до сишной функции (библиотечные и квиковские функции тоже сишные).
 
Цитата
Anton написал:
встали на локе, пока второй поток не соизволит вас пустить
  В нативном коде Lua лок пустая операция во всех функциях C-API.
  Откуда известно, что в QLua лок - синхронизирующая операция во всех функциях С-API QLua, порождающая то, что вы описали? Дело в том, что при выполнении функции (в своей отдельной области стека), в которой используются только общие, не изменяемые, глобальные переменные, синхронизация не требуется . Я думаю, что разработчики QUIK это, наверное, понимают и не подавляют параллелизм выполнения таких функций ( а они есть).  
 
Цитата
TGB написал:
Я думаю, что разработчики QUIK это, наверное, понимают и не подавляют параллелизм выполнения таких функций
Везде, где в кондовом луа стоит lua_lock, в qlua происходит EnterCriticalSection. Это что касается скриптов (не индикаторов).
 
Цитата
TGB написал:
В нативном коде Lua лок пустая операция во всех функциях C-API.
И поэтому "нативный", как вы его назвали, код Lua не предназначен для многопоточного выполнения.Хотите многопоточности - необходимо прописать реализацию функции lua_lock, что в QLua, очевидно, и сделано.
 
Цитата
TGB написал:
Я думаю, что разработчики QUIK это, наверное, понимают и не подавляют параллелизм выполнения таких функций ( а они есть).
Разработчики QUIK, очевидно, не могут сделать что-то другое, кроме как использовать блокировки, встроенные в Lua. А блокировки там сделаны так, что никакого "умного" блокирования не производят. В самом деле: как интерпретатору Lua различать хранение локальных и не локальных переменных? в обычных компиляторах с локальными переменными в разных потоках все просто, ибо они размещаются на стеке - волшебно выделяемом / освобождаемом ресурсе, но Lua-переменные - штуки более сложные, плюс с управляемым временем жизни через сборщик мусора. Так что увы, волшебства никто делать не будет.
 
Цитата
Христиан написал:
как будет работать main() в отдельном потоке при наличии только 1 ядра? Все ли будет работать или нужно минимум 2. Поправьте если я чего-то не понимаю, спасибо

Да, все будет работать.
Как именно - зависит от вашего скрипта.
Если у вас main просыпается раз в 100 мс и просто проверяет не нажата ли кнопка "стоп", посл чего снова уходит в sleep(100) - то не проблема.
Если же у вас main постоянно работает не засыпая на sleep и загружает полностью одно ядро - то, увы, общая скорость работы терминала в такой схеме заметно просядет, т.к. терминал будет делить единственное ядро с постоянно загруженным потоком main.
 
Цитата
Anton написал:
Выделю в процитированном для привлечения внимания
Цитатав
каждый момент времени с луа работает либо мейн, либо колбек.
Хочешь сказать когда Квик в колбеке - майн стоит?
Он же в отдельном потоке? Или там какая-то внутренняя кухня луа, не позволяющая одновременно двум стейтам из двух потоков работать?
 
Цитата
Imersio Arrigo написал:
Или там какая-то внутренняя кухня луа, не позволяющая одновременно двум стейтам из двух потоков работать?
Там критическая секция. Луа выполняется всегда под ней, выпускает только когда сишную функцию вызывает. Получается что от сишной до сишной строго по одному. Сами сишные могут параллельно, но обычно там через три инструкции lua_то и lua_сё, так что кроме лишних переключений контекста ничего не будет.
 
Цитата
Imersio Arrigo написал:
Цитата
Anton написал:
Выделю в процитированном для привлечения внимания
Цитатав
каждый момент времени с луа работает либо мейн, либо колбек.
Хочешь сказать когда Квик в колбеке - майн стоит?
Он же в отдельном потоке? Или там какая-то внутренняя кухня луа, не позволяющая одновременно двум стейтам из двух потоков работать?
Нет, в квике доступ к таблицам потокобезопасный. Соотвественно, если доступ к одной таблице может получить только один поток, другие будут ждать.
 
Для сомневающихся пруф. В колбеке выполняем достаточно долгую операцию и смотрим, успел ли мейн за это время поменять глобальный счетчик. Если успел, выводим сообщение. Сообщений не будет, то есть мейн не может поменять счетчик, пока не вернется OnParam. Существенно, что в колбеке нет сишных вызовов, то есть лок удерживается все время. Если раскомментировать sleep(0) (он сишный), сообщения будут появляться, т.е. мейн будет успевать прорваться к луа, пока выполняется слип.

Запуская этот скрипт, будьте готовы прибивать квик через диспетчер задач.
Код
local run = true
local counter = 0

local function hung(n)
   --sleep(0)
   if n > 0 then
      return hung(n - 1)
   end
   return 0
end

function OnParam()
   local oc = counter
   hung(1000000)
   local nc = counter
   if oc ~= nc then
      message('Counter changed during OnParam execution')
   end
end

function OnStop()
   run = false
end

function main()
   while run do
      counter = counter + 1
      sleep(0)
   end
end
 
Какой-то несходняк.
Если бы колбек залочивал глобучий синхронизатор, то внезависимости от наличия слипа внутри, в майн мы никогда бы не зашли.
т.е. приведенный код работал бы до первого срабатывания OnParam(), а после него весь квичок повиснет навеки независимо от наличия в нем слипа.

А соообщений нет изза того что пока висит колбек - квичек не процессит виндовые сообщения. Как только мы добавляем sleep(0) - оконные сообщения начинают обрабатывать и мы видим мессаги.

Мне кажется, если бы в майне задействовать функцию, которая никак не зависит от работы самого квичка - например вывод в файл. И тогда - прекращение вывода при залипании коллбека - было показателем того что колбеки и майн работают под единым локом. (правда я не уверен что вывод в файл в луа умеет в асиннхронность)
 
Цитата
Anton написал:
Существенно, что в колбеке нет сишных вызовов, то есть лок удерживается все время
И кстати.  Если лок удерживается все время, то наличие сишных вызовов не должно влиять на работу коллбеков никак.
А в его снятие при вызове этих сишных вызовов я верю еще меньше.
 
Цитата
Imersio Arrigo написал:
я верю еще меньше
Это не вопрос веры. Это вопрос взять и в сорцы луа посмотреть. Конкретно luaD_precall
Код
      lua_unlock(L);
      n = (*f)(L);  /* do the actual call */
      lua_lock(L);
Вы код невнимательно смотрели, там не вечная рекурсия, просто достаточно долгая. Ничего навеки виснуть не должно. Слип в виде сишной функции, конечно, я зря выбрал, сбивает с толку. Вот вам получше тестик. Запускаете как есть - видите сообщения с текущим счетчиком (чтобы не говорили, что их квик сожрал). Раскомментируете getWorkingFolder - видите сообщения об изменении счетчика во время работы колбека. Уж эта-то функция никак на обработку сообщений не влияет, она тупо делает GetModuleFileName и lua_pushstring и ничего более.
Код
local run = true
local cbmsg = nil
local counter = 0

local function hung(n)
   --getWorkingFolder()
   if n > 0 then
      return hung(n - 1)
   end
   return 0
end

function OnParam()
   if cbmsg then
      return
   end
   local oc = counter
   hung(1000)
   local nc = counter
   if oc ~= nc then
      cbmsg = 'Counter changed during OnParam execution'
   end
end

function OnStop()
   run = false
end

function main()
   local lastmsgtime = os.clock()
   while run do
      counter = counter + 1
      local msg = cbmsg
      cbmsg = nil
      if msg then
         message(msg)
      else
         local t = os.clock()
         if (t - lastmsgtime) > 3 then
            lastmsgtime = t
            message('' .. counter)
         end
      end
      sleep(1)
   end
end
 
Господа, объясните мне, дураку, на кой вам всё это надо? Торговля на бирже - процесс медленный, вдумчивый, процессы длятся месяцами, даже годами, и потому задержка на минуту, час, день, неделю существенно на результат не влияет. Вы что, делаете сотни и тысячи сделок в час? Но ведь даже в этом случае времени просто ВАГОН! Одно ядро, два, десять, тысяча, C или Lua - ну какая разница?! Не понимаю...
 
Цитата
Владимир написал:
времени просто ВАГОН!
Как обычно, ответ содержится в вопросе )
 
Anton, Я не вижу ответа, хотя вопрос задавал сам. Я не понимаю смысла всех этих изысканий, жуткого обилия разных функций и ловли микросекунд.
 
Цитата
Владимир написал:
Я не понимаю смысла всех этих изысканий, жуткого обилия разных функций и ловли микросекунд.
Тут одни утверждают, что яйца надо с тупого конца бить, другие - что с острого, а я говорю, что вообще надо сбоку. Все вместе мы пытаемся показать, какие мы крутые программисты, какие тонкости знаем и какие трюки можем выделывать. Естественно, для того, чтобы государь узнал про нашу великую дружбу и пожаловал нас генералами.
 
Anton, Похоже на правду.  Но я уже пенсионер, и давным-давно всё показал. Вот и удивляюсь.  :smile:  
 
Цитата
Anton написал:
Это не вопрос веры. Это вопрос взять и в сорцы луа посмотреть. Конкретно  luaD_precall Код
     lua_unlock(L);
     n = (*f)(L);  /* do the actual call */
     lua_lock(L);
Это конечно разрывает мне моск.
Но, видимо остается только следовать известному утверждению: максимально быстро отпускать колбек.
 
Цитата
Христиан написал:
Здравствуйте, хочу поставить Quik на VPS сервер чтобы работал там круглосуточно, волнует вопрос, как будет работать main() в отдельном потоке при наличии только 1 ядра? Все ли будет работать или нужно минимум 2. Поправьте если я чего-то не понимаю, спасибо
все будет работать без проблем, если хватит памяти и места на диске.
Страницы: 1
Читают тему (гостей: 1)
Наверх