Сообщение Вопрос про неблокирующий буфер от 28.04.2015 19:37
Изменено 28.04.2015 19:38 SergASh
Привет всем!
Имеем класс MessageGateway, скелет которого ниже. Идея в том, что из разных потоков
вызывается MessageGateway.Instance.ConveyMessage( "что-то там..." ), сообщению присваивается
порядковый номер и метка времени. После этого сообщение передается дальше по конвейеру (здесь не показано).
Из другого потока код может попросить отдать ему все (GetAllMessages) или часть сообщений (GetRecentMessages).
Требуется:
1. В любой момент времени хранить не более N сообщений.
2. Не хранить сообщения, добавленные ранее, чем M секунд назад.
3. Потокобезопасно отдавать все актуальные сообщения (GetAllMessages)
4. Потокобезопасно отдавать сообщения с порядковым номером большим некоторого произвольного числа (GetRecentMessages)
5. Не блокировать поток при вызове ConveyMessage.
6. Не копировать сообщения в GetAllMessages и в GetRecentMessages.
7. Неохотно, но готов смириться с блокировкой при вызове GetAllMessages и GetRecentMessages, но они не должны блокировать добавление новых сообщений.
1 решается кольцевым буфером. 2-4 можно решить обвешав все локами.
Насколько я понимаю, обычный лок ничем не поможет, если надо вернуть перечислитель.
Тут надо либо копировать всю последовательность, то есть прости-прощай №6, либо вызывать Monitor.Exit из метода Dispose перечислителя.
В последнем случае если про Dispose забудут, то все ляжет.
Как сделать №5 пока не представляю.
Имеем класс MessageGateway, скелет которого ниже. Идея в том, что из разных потоков
вызывается MessageGateway.Instance.ConveyMessage( "что-то там..." ), сообщению присваивается
порядковый номер и метка времени. После этого сообщение передается дальше по конвейеру (здесь не показано).
Из другого потока код может попросить отдать ему все (GetAllMessages) или часть сообщений (GetRecentMessages).
Требуется:
1. В любой момент времени хранить не более N сообщений.
2. Не хранить сообщения, добавленные ранее, чем M секунд назад.
3. Потокобезопасно отдавать все актуальные сообщения (GetAllMessages)
4. Потокобезопасно отдавать сообщения с порядковым номером большим некоторого произвольного числа (GetRecentMessages)
5. Не блокировать поток при вызове ConveyMessage.
6. Не копировать сообщения в GetAllMessages и в GetRecentMessages.
7. Неохотно, но готов смириться с блокировкой при вызове GetAllMessages и GetRecentMessages, но они не должны блокировать добавление новых сообщений.
1 решается кольцевым буфером. 2-4 можно решить обвешав все локами.
Насколько я понимаю, обычный лок ничем не поможет, если надо вернуть перечислитель.
Тут надо либо копировать всю последовательность, то есть прости-прощай №6, либо вызывать Monitor.Exit из метода Dispose перечислителя.
В последнем случае если про Dispose забудут, то все ляжет.
Как сделать №5 пока не представляю.
Скрытый текст | |
| |
Вопрос про неблокирующий буфер
Привет всем!
Имеем класс MessageGateway, скелет которого ниже. Идея в том, что из разных потоков
вызывается MessageGateway.Instance.ConveyMessage( "что-то там..." ), сообщению присваивается
порядковый номер и метка времени. После этого сообщение передается дальше по конвейеру (здесь не показано).
Из другого потока код может попросить отдать ему все (GetAllMessages) или часть сообщений (GetRecentMessages).
Требуется:
1. В любой момент времени хранить не более N сообщений.
2. Не хранить сообщения, добавленные ранее, чем M секунд назад.
3. Потокобезопасно отдавать все актуальные сообщения (GetAllMessages)
4. Потокобезопасно отдавать сообщения с порядковым номером большим некоторого произвольного числа (GetRecentMessages)
5. Не блокировать поток при вызове ConveyMessage.
6. Не копировать сообщения в GetAllMessages и в GetRecentMessages.
7. Неохотно, но готов смириться с блокировкой при вызове GetAllMessages и GetRecentMessages, но они не должны блокировать добавление новых сообщений.
1 решается кольцевым буфером. 2-4 можно решить обвешав все локами.
Насколько я понимаю, обычный лок ничем не поможет, если надо вернуть перечислитель.
Тут надо либо копировать всю последовательность, то есть прости-прощай №6, либо вызывать Monitor.Exit из метода Dispose перечислителя.
В последнем случае если про Dispose забудут, то все ляжет.
Как сделать №5 пока не представляю.
Имеем класс MessageGateway, скелет которого ниже. Идея в том, что из разных потоков
вызывается MessageGateway.Instance.ConveyMessage( "что-то там..." ), сообщению присваивается
порядковый номер и метка времени. После этого сообщение передается дальше по конвейеру (здесь не показано).
Из другого потока код может попросить отдать ему все (GetAllMessages) или часть сообщений (GetRecentMessages).
Требуется:
1. В любой момент времени хранить не более N сообщений.
2. Не хранить сообщения, добавленные ранее, чем M секунд назад.
3. Потокобезопасно отдавать все актуальные сообщения (GetAllMessages)
4. Потокобезопасно отдавать сообщения с порядковым номером большим некоторого произвольного числа (GetRecentMessages)
5. Не блокировать поток при вызове ConveyMessage.
6. Не копировать сообщения в GetAllMessages и в GetRecentMessages.
7. Неохотно, но готов смириться с блокировкой при вызове GetAllMessages и GetRecentMessages, но они не должны блокировать добавление новых сообщений.
1 решается кольцевым буфером. 2-4 можно решить обвешав все локами.
Насколько я понимаю, обычный лок ничем не поможет, если надо вернуть перечислитель.
Тут надо либо копировать всю последовательность, то есть прости-прощай №6, либо вызывать Monitor.Exit из метода Dispose перечислителя.
В последнем случае если про Dispose забудут, то все ляжет.
Как сделать №5 пока не представляю.
Скрытый текст | |
| |