Создать копию очереди
Модератор: Дед Пахом
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
-
- Старожил
- Сообщения: 238
- Зарегистрирован: 10 Ноябрь 2005, 23:07
- Откуда: Краснодар
- Благодарил (а): 6 раз
Создать копию очереди
Здравствуйте, коллеги!
Впервые столкнулся с задачей клонирования очереди.
Имеется некая глобальная очередь, например, BasicQueue.
В отдельной процедуре нужна ее полная копия. Пользуясь документацией по языку сделал (в этой процедуре) следующее:
- в секции данных:
NewQueue &BasicQueue !запрототипировал
- в секции CODE:
NewQueue &= NEW(BasicQueue) !создал копию по образу и подобию
NewQueue &= BasicQueue !скопировал содержимое
Все ли правильно я сделал?
Если да, то почему:
- программа виснет при попытке освободить память оператором Dispose(NewQueue)
- при очистке BasicQueue очищается и NewQueue?
Если нет, то где мой затык в понимании работы с данным механизмом клонирования?
С6.3 ABC
Впервые столкнулся с задачей клонирования очереди.
Имеется некая глобальная очередь, например, BasicQueue.
В отдельной процедуре нужна ее полная копия. Пользуясь документацией по языку сделал (в этой процедуре) следующее:
- в секции данных:
NewQueue &BasicQueue !запрототипировал
- в секции CODE:
NewQueue &= NEW(BasicQueue) !создал копию по образу и подобию
NewQueue &= BasicQueue !скопировал содержимое
Все ли правильно я сделал?
Если да, то почему:
- программа виснет при попытке освободить память оператором Dispose(NewQueue)
- при очистке BasicQueue очищается и NewQueue?
Если нет, то где мой затык в понимании работы с данным механизмом клонирования?
С6.3 ABC
-
- ✯ Ветеран ✯
- Сообщения: 5190
- Зарегистрирован: 28 Май 2009, 15:54
- Откуда: Москва
- Благодарил (а): 11 раз
- Поблагодарили: 26 раз
Создать копию очереди
Эта строчка - не копирование. Вы просто адреса совместили и всё, физически очередь осталась одна. Надо сделать честно, оно же тупо. Создать две очереди и в цикле по одной добавить во вторую. К сведению, есть оператор присвоения всей записи:NewUser писал(а):NewQueue &= BasicQueue !скопировал содержимое
Код: Выделить всё
LOC:Queue2 :=: LOC:Queue1
We are hard at work… for you. 

-
- Старожил
- Сообщения: 238
- Зарегистрирован: 10 Ноябрь 2005, 23:07
- Откуда: Краснодар
- Благодарил (а): 6 раз
Создать копию очереди
Я так всю свою кларионовскую жизнь и делал.
Но сейчас назревающая проблема в том, что таких очередей предвидеться много с одной стороны, и нет четкого понимания структуры исходной очереди - с другой.
- Admin
- Администратор
- Сообщения: 4011
- Зарегистрирован: 05 Июль 2005, 15:59
- Откуда: Хабаровск
- Благодарил (а): 53 раза
- Поблагодарили: 33 раза
- Контактная информация:
Создать копию очереди
Задачу бы немного описали. Может народ что другое подскажет. Память тоже не резиновая

Рай совершает ошибки ничуть не реже чем ад. Просто у него хорошая пресса
-
- Старожил
- Сообщения: 238
- Зарегистрирован: 10 Ноябрь 2005, 23:07
- Откуда: Краснодар
- Благодарил (а): 6 раз
Создать копию очереди
Во-первых, спасибо kreator за указание на ошибку!
И, в самом деле, может возможно решить задачу по-иному, нежели так, как это видеться в моей голове.
Имеется процедура, результатом которой является глобальная очередь выходных данных.
Также есть непредвиденное заранее количество процедур, которые обращаются к выше описанной процедуре и, после формирования очередной версии очереди выходных данных, используют эти данные в своих целях.
Кстати, вопрос: возможна ли при таком подходе конфликтная ситуация, возникающая при одновременном обращении к процедуре, формирующей исходную очередь данных?
И, в самом деле, может возможно решить задачу по-иному, нежели так, как это видеться в моей голове.

Имеется процедура, результатом которой является глобальная очередь выходных данных.
Также есть непредвиденное заранее количество процедур, которые обращаются к выше описанной процедуре и, после формирования очередной версии очереди выходных данных, используют эти данные в своих целях.
Кстати, вопрос: возможна ли при таком подходе конфликтная ситуация, возникающая при одновременном обращении к процедуре, формирующей исходную очередь данных?
Создать копию очереди
Если процедуры могут выполняться одновременно (в разных тредах), то да. Всякие манипуляции с глобальной очередью должны блокироваться через критические секции-мьютексы-семафоры...
-
- Старожил
- Сообщения: 238
- Зарегистрирован: 10 Ноябрь 2005, 23:07
- Откуда: Краснодар
- Благодарил (а): 6 раз
Создать копию очереди
Так и есть. Вызываются из разных тредов.
А не могли бы прояснить как правильней/легче реализовать эту самую блокировку через "критические секции-мьютексы-семафоры..." средствами C6.3 ABC?
А не могли бы прояснить как правильней/легче реализовать эту самую блокировку через "критические секции-мьютексы-семафоры..." средствами C6.3 ABC?
-
- Старожил
- Сообщения: 238
- Зарегистрирован: 10 Ноябрь 2005, 23:07
- Откуда: Краснодар
- Благодарил (а): 6 раз
Создать копию очереди
Я бы сделал так.
Завел бы глобальную переменную-флаг, показывающую факт формирования глобальной очереди. Например, GLO:MakedQueue
В начале процедуры, формирующей эту очередь, присваивал бы ей GLO:MakedQueue = 1
После завершения: GLO:MakedQueue = 0
При обращении к данной процедуре проверял бы эту переменную в цикле.
Например:
Или присвоение GLO:MakedQueue = 1 лучше сделать в вызывающей процедуре?
С учетом того, данные для формирования очереди рассчитываются практически мгновенно, это должно работать и работать быстро.
Завел бы глобальную переменную-флаг, показывающую факт формирования глобальной очереди. Например, GLO:MakedQueue
В начале процедуры, формирующей эту очередь, присваивал бы ей GLO:MakedQueue = 1
После завершения: GLO:MakedQueue = 0
При обращении к данной процедуре проверял бы эту переменную в цикле.
Например:
Код: Выделить всё
Loop
IF Not GLO:MakedQueue
BasicQueueProcedure
Break
END
End
С учетом того, данные для формирования очереди рассчитываются практически мгновенно, это должно работать и работать быстро.
-
- ✯ Ветеран ✯
- Сообщения: 5190
- Зарегистрирован: 28 Май 2009, 15:54
- Откуда: Москва
- Благодарил (а): 11 раз
- Поблагодарили: 26 раз
Создать копию очереди
Не очень понял, конечно, задачу. Но зачем использовать глобальную очередь? А, во-вторых, можно поставить на неё флаг "Thread", что автоматически означает новую копию (???). Вообще, чем проще схема, тем лучше работает программа
.

We are hard at work… for you. 

-
- Старожил
- Сообщения: 238
- Зарегистрирован: 10 Ноябрь 2005, 23:07
- Откуда: Краснодар
- Благодарил (а): 6 раз
Создать копию очереди
И я о том же!
А что именно не понятно? Несколькими постами ниже я, как мне кажется, её подробно описал. В том числе и зачем глобальная очередь. Она, по моему соображению, нужна для совместного её использования другими процедурами. Предлагаете перестроить архитектуру программы под другую реализацию описанного процесса? Тогда как?Не очень понял, конечно, задачу.
И еще вопрос.
Исходя из того, что процедур, вызывающих процедуру, формирующую данную глобальную очередь, много, то как быть с разрастающимся количеством этих самых копий?можно поставить на неё флаг "Thread", что автоматически означает новую копию
Создать копию очереди
Не прокатит. Другая задача может вклиниться между установкой флажка и чтением очередиNewUser писал(а): Я бы сделал так.
После завершения: GLO:MakedQueue = 0
При обращении к данной процедуре проверял бы эту переменную в цикле.
Например:Или присвоение GLO:MakedQueue = 1 лучше сделать в вызывающей процедуре?Код: Выделить всё
Loop IF Not GLO:MakedQueue BasicQueueProcedure Break END End
С учетом того, данные для формирования очереди рассчитываются практически мгновенно, это должно работать и работать быстро.
В качестве примера
- задача 1 установила флажок, чтобы читать очередь
- задача 2 закончила чтение и сбросила флажок
- задача 1 крутится в цикле, жрёт процессор и нифига не делает.
- задача 2 установила флажок
- очередь одновременно читается задачами 1 и 2
У меня в реальной программе (скорее всего, накрутил лишнего, но работает )
Код: Выделить всё
CloseQ:Q QUEUE,PRE(CloseQ)
Npp LONG
Thread LONG
Type CSTRING(10)
Executable CSTRING(260)
END
CloseQ:Mutex &IMutex
.....
CloseQ:Mutex &= NewMutex() ! Инициализация один раз в начале программы
.....
! Добавление записи в очередь
CloseQ:Mutex.Wait()
CloseQ:PlanStep+=1
CloseQ:Npp = CloseQ:PlanStep
CloseQ:Type = 'SCR'
CloseQ:Thread = Thread#
Add(CloseQ:Q,1)
CloseQ:Mutex.Release()
! Удаление записи из очереди
CloseQ:Mutex.Wait()
CloseQ:Thread = Thread()
Get(CloseQ:Q, CloseQ:Thread)
if ~ErrorCode()
Delete(CloseQ:Q)
End
CloseQ:Mutex.Release()
- Дед Пахом
- Старичок
- Сообщения: 3306
- Зарегистрирован: 07 Июль 2005, 16:51
- Откуда: Москва, Россия
- Благодарил (а): 15 раз
- Поблагодарили: 51 раз
- Контактная информация:
Создать копию очереди
Проще заполнять не глобальную очередь, а очередь, переданную в процедуру в качестве параметра.
С уважением, ДП
Создать копию очереди
Всяко бывает. Например, в головном окне сидит планировщик, который создаёт список заданий. А другие треды эти задания исполняют.
-
- ✯ Ветеран ✯
- Сообщения: 5190
- Зарегистрирован: 28 Май 2009, 15:54
- Откуда: Москва
- Благодарил (а): 11 раз
- Поблагодарили: 26 раз
Создать копию очереди
Я не понимаю вот это. Если пользователь работает, то он не может одновременно работать в двух процедурах. Если есть какие-то процессы, которые выполняются одновременно, и ещё они могут передавать управление другим процессам, то да, наверно, возможно. Но что это за задача? В Кларионе тяжеловато (на мой взгляд) сделать независимые процессы с равным "приоритетом". Может я не прав, пусть народ поправит.NewUser писал(а):Кстати, вопрос: возможна ли при таком подходе конфликтная ситуация, возникающая при одновременном обращении к процедуре, формирующей исходную очередь данных?
We are hard at work… for you. 

Создать копию очереди
Хрен его знает, сейчас просмотрел приложение - а там аж четыре таких очереди.
Например, хотим запретить одновременное открытие одного документа в нескольких окнах
Создаём очередь - "код документа+тред" (список кодов открытых документов в разных тредах). Хочем мы открыть документ - ищем его код в очереди, если он уже открыт, достаточно окно вперёд вытащить. Закрываем окно - убираем документ из списка. Типичная ситуация - открываем новый документ и тут же закрываем старый. Вроде бы всё правильно, но что будет с этой очередью ? Вот...
Например, хотим запретить одновременное открытие одного документа в нескольких окнах
Создаём очередь - "код документа+тред" (список кодов открытых документов в разных тредах). Хочем мы открыть документ - ищем его код в очереди, если он уже открыт, достаточно окно вперёд вытащить. Закрываем окно - убираем документ из списка. Типичная ситуация - открываем новый документ и тут же закрываем старый. Вроде бы всё правильно, но что будет с этой очередью ? Вот...