Вопрос по архитектуре библиотеки
Atom Ответить
28.02.2011


Добрый день.

Предположим, что необходимо получать данные по инструментам, для этого мы добавляем нужные столбцы в квике и в программе, подписываемся на событие новой записи и изменения данных в таблице Secirities и в обработчике Trader.Connected запускаем экспорт по DDE этой таблицы.
Данные поступают, мы их видим как в обработчиках событий, так и в таблице Trader.Securities. Далее есть два варианта:
1. в любой момент времени мы можем обратиться к данной таблице из кода стратегии и прочитать нужные нам данные;
2. в обработчиках событий копировать поступившие данные в свои структуры и в стратегии работать со своими данными.

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

Теги:


Спасибо:




15 Ответов
Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 28.02.2011
Ответить


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


Это не так. Объекты торговых типов обновляются без какой-либо синхронизации, и не атомарно.
Спасибо:

esper

Фотография
Программист
Дата: 01.03.2011
Ответить


Mikhail Sukhov Перейти
Это не так. Объекты торговых типов обновляются без какой-либо синхронизации, и не атомарно.


Т.о. получается, что когда я в событии изменения записи таблицы (SecurityChanged) копирую данные из пришедшего объекта в свою внутреннюю структуру они могут поменяться? Может имеет смысл добавить хотя SyncRoot для возможности lock-а или сделать по принципу много читателей - один писатель?
Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 01.03.2011
Ответить


esper Перейти
Mikhail Sukhov Перейти
Это не так. Объекты торговых типов обновляются без какой-либо синхронизации, и не атомарно.


Т.о. получается, что когда я в событии изменения записи таблицы (SecurityChanged) копирую данные из пришедшего объекта в свою внутреннюю структуру они могут поменяться? Может имеет смысл добавить хотя SyncRoot для возможности lock-а или сделать по принципу много читателей - один писатель?


А зачем?
Спасибо:

Maxim

Фотография
Дата: 01.03.2011
Ответить


Мне кажется вы друг друга недопонимаете.

На мой взгляд, esper хотел спросить: являются ли свойства объекта класса QuikTrader потокобезопасными?
И насколько я знаю, ответ: да, являются.

Михаил, поправьте меня, если я ошибаюсь.


Попутный уточняющий вопрос:
а все ли свойства потокобезопасны?
В частности интересует свойство Security.ExtensionInfo
Необходима ли синхронизация этого свойства при доступе из разных потоков?
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 01.03.2011
Ответить


Maxim Перейти
В частности интересует свойство Security.ExtensionInfo
Необходима ли синхронизация этого свойства при доступе из разных потоков?


Смотря что Вы с ним хотите делать. Если просто сделать так
Код
var info = sec.ExtensionInfo;
, а если
Код
sec.ExtensionInfo.Contains(key);
то да.
Спасибо:

esper

Фотография
Программист
Дата: 01.03.2011
Ответить


Mikhail Sukhov Перейти
А зачем?


К примеру, у меня стратегия крутится в другом потоке, на каждой итерации ей нужны данные из таблицы инструментов. Получение данных из таблицы осуществляется не в одном месте, а рассредоточено по всей функции стратегии. Я считываю одно поле для конкретного инструмента в начале функции, далее выполняю другие действия, из квика приходят новые данные, считываю другое поле для этого же инструмента и получаю несогласованные данные.

Mikhail Sukhov Перейти
Смотря что Вы с ним хотите делать. Если просто сделать так
Код
var info = sec.ExtensionInfo;
, а если
Код
sec.ExtensionInfo.Contains(key);
то да.


Почему в первом случае нет необходимости в синхронизации? ExtensionInfo вроде ссылочный тип, при таком присваивании данные не копируются, просто получаем еще один указатель на словарьConfused
Автор топика
Спасибо:

Maxim

Фотография
Дата: 01.03.2011
Ответить


Mikhail Sukhov Перейти

Смотря что Вы с ним хотите делать. Если просто сделать так
Код
var info = sec.ExtensionInfo;
, а если
Код
sec.ExtensionInfo.Contains(key);
то да.



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


Я хочу в одном потоке записывать в это свойство данные, а в другом потоке читать эти данные.
Необходимо ли синхронизовать эти потоки, что бы они одновременно не имели доступ к этому свойству?
Или эта синхронизация реализована внутри свойства?
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 01.03.2011
Ответить


Maxim Перейти

Я хочу в одном потоке записывать в это свойство данные, а в другом потоке читать эти данные.
Необходимо ли синхронизовать эти потоки, что бы они одновременно не имели доступ к этому свойству?
Или эта синхронизация реализована внутри свойства?


Да, нужно. Это вариант 2.
Спасибо:

esper

Фотография
Программист
Дата: 01.03.2011
Ответить


Mikhail Sukhov Перейти
Maxim Перейти

Я хочу в одном потоке записывать в это свойство данные, а в другом потоке читать эти данные.
Необходимо ли синхронизовать эти потоки, что бы они одновременно не имели доступ к этому свойству?
Или эта синхронизация реализована внутри свойства?


Да, нужно. Это вариант 2.


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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 01.03.2011
Ответить


esper Перейти
А каким образом можно сделать синхронизацию с внутренним обновлением этих данных? Чтобы пока я их читаю они не менялись?


Наверное никак, так как никакой синхронизации в обновлении данных нет. А в чем заключается сама задача?
Спасибо:

esper

Фотография
Программист
Дата: 01.03.2011
Ответить


Mikhail Sukhov Перейти
esper Перейти
А каким образом можно сделать синхронизацию с внутренним обновлением этих данных? Чтобы пока я их читаю они не менялись?


Наверное никак, так как никакой синхронизации в обновлении данных нет. А в чем заключается сама задача?


К примеру, у меня стратегия крутится в другом потоке, на каждой итерации ей нужны данные из таблицы инструментов. Получение данных из таблицы осуществляется не в одном месте, а рассредоточено по всей функции стратегии. Я считываю одно поле для конкретного инструмента в начале функции, далее выполняю другие действия, из квика приходят новые данные, считываю другое поле для этого же инструмента и получаю несогласованные данные.

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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 01.03.2011
Ответить


esper Перейти
Я считываю одно поле для конкретного инструмента в начале функции, далее выполняю другие действия, из квика приходят новые данные, считываю другое поле для этого же инструмента и получаю несогласованные данные.


Можете эти поля указать?
Спасибо:

Maxim

Фотография
Дата: 04.03.2011
Ответить


Михаил, добрый день.
Еще один вопрос про потоки.

Каким образом можно перебрать все элементы свойства QuikTrader.MyTrades?

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

Соответственно, что бы применить foreach к QuikTrader.MyTrades, нужно на время выполнения этого цикла блокировать
изменение этого свойства. Есть ли такая возможность? Например, публичный объект для блокировки?


Или есть другой способ выполнить задачу?
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 04.03.2011
Ответить


Maxim Перейти
Михаил, добрый день.
Еще один вопрос про потоки.

Каким образом можно перебрать все элементы свойства QuikTrader.MyTrades?


Напрямую. Всегда возвращается копия данных, которая не модифицируется.

Maxim Перейти

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


Попробуйте так сделать. Ошибка будет совсем другая.

Maxim Перейти

Соответственно, что бы применить foreach к QuikTrader.MyTrades, нужно на время выполнения этого цикла блокировать
изменение этого свойства. Есть ли такая возможность? Например, публичный объект для блокировки?


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

Maxim

Фотография
Дата: 04.03.2011
Ответить


Mikhail Sukhov Перейти

Напрямую. Всегда возвращается копия данных, которая не модифицируется.


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

Итак, насколько я понял если во время выполнения следующего кода
из Квика придет новая моя сделка, то она в цикл никак не попадет?
Код

foreach (MyTrade myTrade in Global.Quik.MyTrades)
if (_newOrder == myTrade.Order)
_volume += myTrade.Trade.Volume;





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


Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy