У меня работает несколько роботов с выводом данных каждый в свою таблицу. Возникла необходимость сделать сводную таблицу для всех. Пока не понимаю как передавать данные из скрипта в скрипт. Вернее одно решение есть - отдавать через сохраняемый и затем читаемый файл, но во первых это криво, во вторых медленно. Буду благодарен за рабочую идею.
Опять же скрипты роботов должны постоянно проверять этот файл не сменился ли идентификатор в связи с перезапуском скрипта таблицы. Гемор с постоянным обращением к диску.
Kolossi, Подкидываю идею: объединить "несколько роботов" в один и не мучиться.
Ну, а если не хочется, то есть только два способа: через файл и через ОЗУ двойного доступа (для Lua нереально). Поэтому (если s_mike прав) пусть ГЛАВНЫЙ скрипт, запускаемый первым, создаёт эту общую таблицу, записывает её ID в файл, а остальные читают при запуске. А скрипты могут ничего не проверять, если "главный скрипт" по выходу убьёт их всех (правда, я не знаю как это сделать и можно ли сделать вообще).
s_mike@rambler.ru написал: Имея номер окна, можно писать в него из любых скриптов.
Не знаю, может у меня версия квика какая-то другая. Но нумерация окон не сквозная, у каждого скрипта своя, начинающаяся с 1. Т.е., идентификаторы окон разных скриптов могут совпадать. И писать в окно другого скрипта не получается.
Надо делать так, как надо. А как не надо - делать не надо.
s_mike@rambler.ru написал: Имея номер окна, можно писать в него из любых скриптов.
Не знаю, может у меня версия квика какая-то другая. Но нумерация окон не сквозная, у каждого скрипта своя, начинающаяся с 1. Т.е., идентификаторы окон разных скриптов могут совпадать. И писать в окно другого скрипта не получается.
Kolossi написал: Номер окна выдает каждый раз следующий.16-17-18-19... и так по порядку каждый раз при убиении и запуске скрипта.
Так и есть. При перезапуске скрипта идентификаторы новых окон увеличиваются.
Цитата
Nikolay написал: Вариант 3 - файлы. Но взаимные блокировки будет проблемой.
Вот тут пример организации обмена с двумя файлами: 1-й файл для передачи данных, 2-й - пустой файл, служит флагом для индикации готовности данных к считыванию.
Надо делать так, как надо. А как не надо - делать не надо.
Проверил. Нумерация окон меняется конкретно для каждого скрипта-увеличивается с каждым перезапуском начиная с запуска Квика. Запустив два одинаковых скрипта при помощи перезапусков легко получил окна с одинаковыми идентификаторами. Облом.
Старатель написал: Вот тут пример организации обмена с двумя файлами: 1-й файл для передачи данных, 2-й - пустой файл, служит флагом для индикации готовности данных к считыванию.
И я плавно приехал от идеи общей таблицы к необходимости замены hdd на ssd
Старатель написал: Вот тут пример организации обмена с двумя файлами: 1-й файл для передачи данных, 2-й - пустой файл, служит флагом для индикации готовности данных к считыванию.
Это надо для каждый пары источник-приемник создавать пару файлов. Как только несколько писателей, с двумя файлами может быть блокировка. А приемник должен псевдо-асинхронно это читать.
Kolossi написал: Проверил. Нумерация окон меняется конкретно для каждого скрипта-увеличивается с каждым перезапуском начиная с запуска Квика. Запустив два одинаковых скрипта при помощи перезапусков легко получил окна с одинаковыми идентификаторами. Облом.
Nikolay написал: Это надо для каждый пары источник-приемник создавать пару файлов. Как только несколько писателей, с двумя файлами может быть блокировка.
Второй файл как раз служит для писателей индикатором, что первый файл занят, и запись не возможна. Как только приёмник прочитает данные, он удаляет 2-й файл, что сигнализирует о возможности записи. Т.е. организуются синхронные запись/чтение.
Кстати, ни разу не видел, блокировок файлов, одновременно открытых несколькими Lua-скриптами. Если файл открыт другим приложением, то, да, было.
Надо делать так, как надо. А как не надо - делать не надо.
Старатель написал: Второй файл как раз служит для писателей индикатором, что первый файл занят, и запись не возможна. Как только приёмник прочитает данные, он удаляет 2-й файл, что сигнализирует о возможности записи. Т.е. организуются синхронные запись/чтение.
Кстати, ни разу не видел, блокировок файлов, одновременно открытых несколькими Lua-скриптами. Если файл открыт другим приложением, то, да, было.
Блокировки видел, хоть lua и очень быстр в части работы с файлами. Если пара одна, то это приведет к тому, что все будут ждать пока он освободится. А если несколько, то приемник сможет переключаться между парами, чтобы не ждать.
Конечно, все это для обмена большими объемами и несколькими источниками-потребителями. Если данных мало и они редки, то все это излишне.
Старатель написал: Второй файл как раз служит для писателей индикатором, что первый файл занят, и запись не возможна. Как только приёмник прочитает данные, он удаляет 2-й файл, что сигнализирует о возможности записи. Т.е. организуются синхронные запись/чтение.
Кстати, ни разу не видел, блокировок файлов, одновременно открытых несколькими Lua-скриптами. Если файл открыт другим приложением, то, да, было.
Блокировки видел, хоть lua и очень быстр в части работы с файлами. Если пара одна, то это приведет к тому, что все будут ждать пока он освободится. А если несколько, то приемник сможет переключаться между парами, чтобы не ждать.
Конечно, все это для обмена большими объемами и несколькими источниками-потребителями. Если данных мало и они редки, то все это излишне.
lua открывает файлы в разделяемом режиме. Поэтому блокировок не бывает. Файл нужно просто читать и проверять целостность данных.
Для чтения. Записать одновременно в один файл с двух сторон, то еще занятие. Да, файл-флаг здесь решит проблему, чтоб все ждали пока он есть. А когда его нет, то все писатели одновременно ринутся писать в один тот-же файл.
Если источник-приемник один, то достаточно в источнике открыть файл в режиме записи, а в приемнике в режиме чтения и просто проверять новые данные в этом файле через read("*l"). Писатель записал, читатель их прочитал. Скрипт индикатору может спокойно так передавать информацию.
Nikolay написал: Конечно, все это для обмена большими объемами и несколькими источниками-потребителями. Если данных мало и они редки, то все это излишне.
ТС задал вопрос по выводу данных в общую визуальную таблицу. Врядли там большие объёмы данных.
Цитата
Nikolay написал: Если пара одна, то это приведет к тому, что все будут ждать пока он освободится.
А в других перечисленных вами вариантах ждать не будут?
Цитата
Nikolay написал: Если источник-приемник один, то достаточно в источнике открыть файл в режиме записи, а в приемнике в режиме чтения и просто проверять новые данные в этом файле через read("*l").
Можно и так. Тогда отпадает необходимость в открытии/зактытии/удалении файлов, что затратно.
Надо делать так, как надо. А как не надо - делать не надо.
Старатель написал: Второй файл как раз служит для писателей индикатором, что первый файл занят, и запись не возможна.Как только приёмник прочитает данные, он удаляет 2-й файл, что сигнализирует о возможности записи.Т.е. организуются синхронные запись/чтение.
Я делаю так же, только с одним файлом. Передатчик создает файл и пишет туда инфу. Приемник смотрит наличие этого файла. Для него это флаг, что можно читать свежую инфу. Он (приемник) ее читает и удаляет файл. Для передатчика отсутствие файла означает, что файл прочитан и можно создавать файл для передачи новой инфы. Если это и хуже варианта с двумя файлами, то интересно чем?
Игорь Б, По условию там вроде как МНОЖЕСТВО скриптов, и все они должны ПИСАТЬ, готовя сводную таблицу. Я вижу такое решение файл - один, но для каждого скрипта выделяется собственное пространство (фиксированного объёма). Далее они читают и пишут только в свои зоны, а общий диспетчер (который эту таблицу формирует) ставит флаги "прочитано, можно писать следующую порцию". В любом случае, работа множества скриптов с обменом информацией через файл есть геморрой.
А в других перечисленных вами вариантах ждать не будут?
Так смотря что ждать. Если база данных, то смотрим какой уровень изоляции транзакции оная поддерживает. Можно сделать несколько таблиц для каждой пары (примерно как и с файлами). Писатель блокирует таблицу, другие таблицы доступны. Читатель читает те таблицы, что доступны.
Если библиотеки обмена, то их авторы доступны.
Если socket, то он по умолчанию блокирующий. Т.е. надо ждать. В книге Роберту Иерузалимски. «Программирование на языке Lua» есть пример Невытесняющая многонитевость.
named pipes позволяют сделать многопоточное подключение, к серверу. Хотя именованные каналы - это по сути файлы, только в памяти.
Kolossi написал: Проверил. Нумерация окон меняется конкретно для каждого скрипта-увеличивается с каждым перезапуском начиная с запуска Квика. Запустив два одинаковых скрипта при помощи перезапусков легко получил окна с одинаковыми идентификаторами. Облом.
Один скрипт выводит все таблицы, включая "сводную", другой кидает ему данные через
Nikolay написал: Если источник-приемник один, то достаточно в источнике открыть файл в режиме записи, а в приемнике в режиме чтения и просто проверять новые данные в этом файле через read("*l").
Можно и так. Тогда отпадает необходимость в открытии/зактытии/удалении файлов, что затратно.
При частой записи данных файл обмена может сильно разрастись. В этом случае есть сомнения в скорости сброса данных на диск. Маленькие файлы кешируются в памяти операционной системой, а большие? Не получится ли так, что каждый новый flush будет дольше предыдущего?
Цитата
Игорь Б написал: Я делаю так же, только с одним файлом. Передатчик создает файл и пишет туда инфу. Приемник смотрит наличие этого файла. Для него это флаг, что можно читать свежую инфу. Он (приемник) ее читает и удаляет файл. Для передатчика отсутствие файла означает, что файл прочитан и можно создавать файл для передачи новой инфы. Если это и хуже варианта с двумя файлами, то интересно чем?
Думаю, не хуже. Но в обоих случаях при одновременном открытии файла обмена несколькими источниками гипотетически часть данных может быть потеряна.
Цитата
Владимир написал: файл - один, но для каждого скрипта выделяется собственное пространство (фиксированного объёма). Далее они читают и пишут только в свои зоны, а общий диспетчер (который эту таблицу формирует) ставит флаги "прочитано, можно писать следующую порцию".
Вариант, заслуживающий внимания.
Ещё вариант: читать/писать под локом. Файл один, открывается один раз, при остановке скрипта закрывается. Данные записываются в режиме изменения в начало файла, сообщение добивается нулями до фиксированной длины.
Надо делать так, как надо. А как не надо - делать не надо.
Swerg огромное спасибо за библиотеку !!! Все работает как хотелось. Дальше дело техники - передать цветовые коды и тп.
К сожалению часть таблиц, которые хотелось бы вынести в общие, обрабатывают мышинный callback и решения как его отдать из скрипта общей таблицы роботу с созданием параллельного потока я не вижу.
Если у Вас ячейки привязаны к конкретному скрипту (т.е. реакция на нее однозначно для скрипта №2), особой разницы нет, где событие прошло. Делаете очередь событий и передаете события с параметрами обратно в скрипт через тот же механизм. А скрипт уже, в свою очередь, опрашивает на предмет нового события из своей области обмена.
Nikolay, Оба-на! Я когда-то занимался диалоговыми программами, и у меня всегда имело ОГРОМНОЕ значение, где событие прошло! В частности, обработчики событий в главном и контекстном меню моего скрипта совершенно разные. Кроме того, "очередь событий" автоматически делает невозможной иметь объект реакции типа "группа событий", что накладывает просто крест на хоть сколько-нибудь сложном диалоге. Наконец, обмен событиями между скриптами (тем более, на Lua) - это идеологический маразм, это не будет работать НИКОГДА! В крайнем (и далеко не лучшем ) случае это будет служить ВЕЧНЫМ источником глюков. А глюков в Lua и без того более, чем достаточно.
Раз необходимо иметь разные события для разных окон, то дайте имена этим событиям разные или сопровождайте их разным наборов параметров, чтобы обработчик понимал с чем имеет дело.
А что касается интерфейса, то он может быть расположен на устройстве на Марсе. А сервер должен получить события, что пользователь инициировал и как-то прореагировать: ракету запустить или вернуть ответ в тот же интерфейс. Интерфейс и сервер (обработчик и т.д.) это не обязательно единое целое.
Что касается групп событий, то здесь надо формализовать как эта группа формируется. Возможно на клиенте с интерфейсом надо сгруппировать по какому-то признаку и уже передать эту группу в очередь как единое целое.
Nikolay, Лично у меня интерфейс с сервером отсутствует как класс. Интерфейс с Квиком ужат до предела, до пары-тройки утилит. А интерфейс с юзером имеет все возможности, которые вообще можно выжать из чистого Lua.
Да как угодно "эта группа формируется"! Объект реакции на событие типа "группа событий" не может быть втиснут в очередь событий - здесь требуется именно стек очередей, поскольку все объекты этой очереди должны быть обработаны "вне очереди".
Nikolay написал: Если у Вас ячейки привязаны к конкретному скрипту (т.е. реакция на нее однозначно для скрипта №2), особой разницы нет, где событие прошло. Делаете очередь событий и передаете события с параметрами обратно в скрипт через тот же механизм. А скрипт уже, в свою очередь, опрашивает на предмет нового события из своей области обмена.
Легко давать советы не особенно вникая.) Передать колбэк не проблема только вот что бы принять его другим скриптом механизма прерывания и включения параллельного потока нет. Или вы предлагаете main() в цикле опрашивать переменную на случай наступления события?
Легко давать советы не особенно вникая.) Передать колбэк не проблема только вот что бы принять его другим скриптом механизма прерывания и включения параллельного потока нет. Или вы предлагаете main() в цикле опрашивать переменную на случай наступления события?
Да, опрашивать по изменению количества в очереди. Собственно, это не такая и редка задача: Квик исполнитель, а интерфейс может быть в базе данных, на таблицах. Ясно, что лучше написать прямую библиотеку, но раз ее нет, надо передавать команды по каналам связи.
Легко давать советы не особенно вникая.) Передать колбэк не проблема только вот что бы принять его другим скриптом механизма прерывания и включения параллельного потока нет. Или вы предлагаете main() в цикле опрашивать переменную на случай наступления события?
Да, опрашивать по изменению количества в очереди. Собственно, это не такая и редка задача: Квик исполнитель, а интерфейс может быть в базе данных, на таблицах. Ясно, что лучше написать прямую библиотеку, но раз ее нет, надо передавать команды по каналам связи.
Попробую объяснить на пальцах. В скрипте робота есть таблица в которой по дабл-клик на ячейку меняется значение некоторой переменной. Таблица перенесена в другой скрипт. Что дальше? Никаких проблем нет с обработкой клика и передачи этого события в первый скрипт в виде изменения содержимого общей для двух скриптов переменной. Вопрос как ее получить в первом скрипте? Постоянно опрашивая изменение в цикле? Это значит, что в определенном месте обработки скрипта. Замечу, что в первом случае это обрабатывается в параллельном потоке.
Скрипт с таблицей имеет очередь передачи сообщений - она же таблица в staticVаr, допустим. При возникновении события в таблице в эту очередь записывается информация. Как Вы и написали проблем с передачей нет.
Другой скрип, смотрит на эту очередь и читает информацию, если в ней что-то появилось. Опрашивать, допустим по увеличению размера. Не такая и проблема выполнить что-то типа: last_count < #Table
На самом деле, даже если это один скрипт, некоторые команды нежелательно исполнять в колбеке таблицы. А значит их надо передавать в дополнительный поток скрипта, через любую переменную видимого контекста. Это мало отличается от схемы с разделяемой переменной. Неэффективность будет только в том, что все события пойдут через очередь.